/**
 * FormDatePicker Component
 * 
 * A reusable date picker component that handles:
 * - Single date selection
 * - Date range selection
 * - Label
 * - Controller (react-hook-form)
 * - Error handling
 * 
 * This component reduces code duplication for date picker fields across forms.
 */

import React from 'react';
import { Control, Controller, FieldError, FieldPath, FieldValues } from 'react-hook-form';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { CalendarIcon } from 'lucide-react';
import { format } from 'date-fns';
import { DateRange } from 'react-day-picker';
import { cn } from '@/lib/utils';

// =============================================================================
// TYPES
// =============================================================================

export interface FormDatePickerProps<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> {
  // Form control
  control: Control<TFieldValues>;
  name: TName;
  
  // Field configuration
  label?: string;
  placeholder?: string;
  required?: boolean;
  
  // Date picker configuration
  mode?: 'single' | 'range';
  numberOfMonths?: number;
  
  // Styling
  className?: string;
  labelClassName?: string;
  buttonClassName?: string;
  errorClassName?: string;
  
  // Validation
  validation?: {
    required?: boolean | string;
  };
  
  // Additional props
  disabled?: boolean;
  size?: 'sm' | 'md' | 'lg';
  
  // Date formatting
  dateFormat?: string;
  
  // Custom render functions
  renderTrigger?: (props: {
    field: any;
    fieldState: { error?: FieldError };
    selectedDate: Date | DateRange | undefined;
    placeholder: string;
  }) => React.ReactElement;
}

// =============================================================================
// COMPONENT
// =============================================================================

export function FormDatePicker<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
  control,
  name,
  label,
  placeholder = 'Pick a date',
  required = false,
  mode = 'single',
  numberOfMonths = 1,
  className = '',
  labelClassName = '',
  buttonClassName = '',
  errorClassName = '',
  validation,
  disabled = false,
  size = 'md',
  dateFormat = 'LLL dd, y',
  renderTrigger,
}: FormDatePickerProps<TFieldValues, TName>) {
  
  // =============================================================================
  // HELPER FUNCTIONS
  // =============================================================================
  
  const getButtonSize = (size: 'sm' | 'md' | 'lg') => {
    switch (size) {
      case 'sm':
        return 'h-8 text-sm';
      case 'lg':
        return 'h-12 text-base';
      default:
        return 'h-10 text-sm';
    }
  };
  
  const formatDate = (date: Date | DateRange | undefined): string => {
    if (!date) return '';
    
    if (mode === 'range' && 'from' in date) {
      if (date.from) {
        if (date.to) {
          return `${format(date.from, dateFormat)} - ${format(date.to, dateFormat)}`;
        }
        return format(date.from, dateFormat);
      }
    } else if (date instanceof Date) {
      return format(date, dateFormat);
    }
    
    return '';
  };
  
  // =============================================================================
  // RENDER FUNCTIONS
  // =============================================================================
  
  const renderDefaultTrigger = (
    field: any, 
    fieldState: { error?: FieldError },
    selectedDate: Date | DateRange | undefined,
    placeholder: string
  ) => (
    <Button
      variant="outline"
      className={cn(
        'w-full justify-start text-left font-normal transition-colors',
        getButtonSize(size),
        fieldState.error && 'border-destructive focus:border-destructive',
        !selectedDate && 'text-muted-foreground',
        buttonClassName
      )}
      disabled={disabled}
    >
      <CalendarIcon className="mr-2 h-4 w-4" />
      {formatDate(selectedDate) || placeholder}
    </Button>
  );
  
  // =============================================================================
  // MAIN RENDER
  // =============================================================================
  
  return (
    <div className={cn('space-y-2', className)}>
      {/* Label */}
      {label && (
        <Label 
          htmlFor={name} 
          className={cn(
            'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
            required && 'after:content-["*"] after:ml-0.5 after:text-destructive',
            labelClassName
          )}
        >
          {label}
        </Label>
      )}
      
      {/* Controller */}
      <Controller
        control={control}
        name={name}
        rules={{
          required: validation?.required || required,
        }}
        render={({ field, fieldState }) => {
          const selectedDate = field.value;
          
          return (
            <div className="space-y-1">
              <Popover>
                <PopoverTrigger asChild>
                  {renderTrigger ? 
                    renderTrigger({ field, fieldState, selectedDate, placeholder }) :
                    renderDefaultTrigger(field, fieldState, selectedDate, placeholder)
                  }
                </PopoverTrigger>
                
                <PopoverContent className="w-auto p-0" align="start">
                  <Calendar
                    initialFocus
                    mode={mode}
                    defaultMonth={mode === 'range' && 'from' in selectedDate ? selectedDate.from : selectedDate}
                    selected={selectedDate}
                    onSelect={field.onChange}
                    numberOfMonths={numberOfMonths}
                    disabled={disabled}
                  />
                </PopoverContent>
              </Popover>
              
              {/* Error Message */}
              {fieldState.error && (
                <p className={cn(
                  'text-sm text-destructive',
                  errorClassName
                )}>
                  {fieldState.error.message}
                </p>
              )}
            </div>
          );
        }}
      />
    </div>
  );
}

export default FormDatePicker; 