import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
import 'package:lucide_icons_flutter/lucide_icons.dart' as lucide;
import 'package:shadcn_ui/shadcn_ui.dart';

/// 단일 날짜 선택을 위한 공통 버튼 위젯.
class SuperportDatePickerButton extends StatelessWidget {
  const SuperportDatePickerButton({
    super.key,
    required this.value,
    required this.onChanged,
    this.firstDate,
    this.lastDate,
    this.dateFormat,
    this.placeholder = '날짜 선택',
    this.enabled = true,
    this.initialDate,
  });

  final DateTime? value;
  final ValueChanged<DateTime> onChanged;
  final DateTime? firstDate;
  final DateTime? lastDate;
  final intl.DateFormat? dateFormat;
  final String placeholder;
  final bool enabled;
  final DateTime? initialDate;

  @override
  Widget build(BuildContext context) {
    final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
    final displayText = value != null ? format.format(value!) : placeholder;
    return ShadButton.outline(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      gap: 8,
      onPressed: !enabled
          ? null
          : () async {
              final now = DateTime.now();
              final baseFirst = firstDate ?? DateTime(now.year - 10);
              final baseLast = lastDate ?? DateTime(now.year + 5);
              final seed = value ?? initialDate ?? now;
              final adjustedInitial = seed.clamp(baseFirst, baseLast);
              final picked = await showDatePicker(
                context: context,
                initialDate: adjustedInitial,
                firstDate: baseFirst,
                lastDate: baseLast,
              );
              if (picked != null) {
                onChanged(picked);
              }
            },
      trailing: const Icon(lucide.LucideIcons.calendar, size: 16),
      child: Text(
        displayText,
        maxLines: 1,
        overflow: TextOverflow.ellipsis,
        softWrap: false,
        textAlign: TextAlign.left,
      ),
    );
  }
}

/// 날짜 범위 선택을 위한 공통 버튼 위젯.
class SuperportDateRangePickerButton extends StatelessWidget {
  const SuperportDateRangePickerButton({
    super.key,
    required this.value,
    required this.onChanged,
    this.firstDate,
    this.lastDate,
    this.dateFormat,
    this.placeholder = '기간 선택',
    this.enabled = true,
    this.initialDateRange,
  });

  final DateTimeRange? value;
  final ValueChanged<DateTimeRange?> onChanged;
  final DateTime? firstDate;
  final DateTime? lastDate;
  final intl.DateFormat? dateFormat;
  final String placeholder;
  final bool enabled;
  final DateTimeRange? initialDateRange;

  @override
  Widget build(BuildContext context) {
    final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
    final label = value == null
        ? placeholder
        : '${format.format(value!.start)} ~ ${format.format(value!.end)}';
    return ShadButton.outline(
      gap: 8,
      mainAxisAlignment: MainAxisAlignment.start,
      onPressed: !enabled
          ? null
          : () async {
              final now = DateTime.now();
              final baseFirst = firstDate ?? DateTime(now.year - 10);
              final baseLast = lastDate ?? DateTime(now.year + 5);
              final initialRange = value ?? initialDateRange;
              final currentDate = initialRange?.start ?? now;
              final picked = await showDateRangePicker(
                context: context,
                firstDate: baseFirst,
                lastDate: baseLast,
                initialDateRange: initialRange,
                currentDate: currentDate.clamp(baseFirst, baseLast),
              );
              if (picked != null) {
                onChanged(picked);
              }
            },
      leading: const Icon(lucide.LucideIcons.calendar, size: 16),
      child: Text(
        label,
        maxLines: 1,
        overflow: TextOverflow.ellipsis,
        softWrap: false,
        textAlign: TextAlign.left,
      ),
    );
  }
}

extension _ClampDate on DateTime {
  DateTime clamp(DateTime min, DateTime max) {
    if (isBefore(min)) return min;
    if (isAfter(max)) return max;
    return this;
  }
}
