'use client';

import { useState } from 'react';
import { useTranslations } from 'next-intl';
import { format, differenceInBusinessDays, addDays } from 'date-fns';
import { de, enUS } from 'date-fns/locale';
import {
  Calendar as CalendarIcon,
  Palmtree,
  Thermometer,
  Home,
  Star,
  CalendarOff,
  GraduationCap,
  Send,
  Baby,
  Heart,
  Plane,
  Clock,
} from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Switch } from '@/components/ui/switch';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { useCreateAbsenceRequest } from '@/hooks/hr/use-absences';
import { useToast } from '@/hooks/use-toast';
import { cn } from '@/lib/utils';
import type { AbsenceType, CreateAbsenceDto } from '@/types/hr';
import { ABSENCE_TYPE_INFO } from '@/types/hr';

interface AbsenceRequestFormProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  locale: string;
}

const ABSENCE_ICONS: Record<AbsenceType, typeof Palmtree> = {
  VACATION: Palmtree,
  SICK: Thermometer,
  SICK_CHILD: Baby,
  HOME_OFFICE: Home,
  SPECIAL_LEAVE: Star,
  UNPAID_LEAVE: CalendarOff,
  PARENTAL_LEAVE: Heart,
  BUSINESS_TRIP: Plane,
  TRAINING: GraduationCap,
  COMPENSATION: Clock,
};

/**
 * Form for creating a new absence request
 */
export function AbsenceRequestForm({ open, onOpenChange, locale }: AbsenceRequestFormProps) {
  const t = useTranslations('hr.absences');
  const tAbsenceTypes = useTranslations('hr.absenceTypes');
  const tCommon = useTranslations('common');
  const { toast } = useToast();
  const dateLocale = locale === 'de' ? de : enUS;

  const createRequest = useCreateAbsenceRequest();

  // Form state
  const [formData, setFormData] = useState<Partial<CreateAbsenceDto>>({
    type: 'VACATION',
    startDate: format(addDays(new Date(), 1), 'yyyy-MM-dd'),
    endDate: format(addDays(new Date(), 1), 'yyyy-MM-dd'),
    halfDay: false,
    halfDayPeriod: undefined,
    note: '',
  });

  // Calculate days
  const calculateDays = () => {
    if (!formData.startDate || !formData.endDate) return 0;
    const start = new Date(formData.startDate);
    const end = new Date(formData.endDate);
    let days = differenceInBusinessDays(end, start) + 1;
    if (formData.halfDay) days = 0.5;
    return Math.max(0, days);
  };

  const days = calculateDays();

  const resetForm = () => {
    setFormData({
      type: 'VACATION',
      startDate: format(addDays(new Date(), 1), 'yyyy-MM-dd'),
      endDate: format(addDays(new Date(), 1), 'yyyy-MM-dd'),
      halfDay: false,
      halfDayPeriod: undefined,
      note: '',
    });
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!formData.type || !formData.startDate || !formData.endDate) {
      toast({
        title: tCommon('error'),
        description: t('fillRequiredFields'),
        variant: 'destructive',
      });
      return;
    }

    if (new Date(formData.startDate) > new Date(formData.endDate)) {
      toast({
        title: tCommon('error'),
        description: t('invalidDateRange'),
        variant: 'destructive',
      });
      return;
    }

    try {
      await createRequest.mutateAsync({
        type: formData.type as AbsenceType,
        startDate: formData.startDate,
        endDate: formData.endDate,
        halfDay: formData.halfDay,
        halfDayPeriod: formData.halfDayPeriod as 'MORNING' | 'AFTERNOON' | undefined,
        note: formData.note,
      });

      toast({
        title: t('requestSubmitted'),
        description: t('requestSubmittedDesc'),
      });

      onOpenChange(false);
      resetForm();
    } catch {
      toast({
        title: tCommon('error'),
        description: t('errorSubmitRequest'),
        variant: 'destructive',
      });
    }
  };

  const absenceTypes = Object.entries(ABSENCE_TYPE_INFO) as [AbsenceType, typeof ABSENCE_TYPE_INFO.VACATION][];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Palmtree className="h-5 w-5" />
            {t('newRequest')}
          </DialogTitle>
          <DialogDescription>{t('newRequestDesc')}</DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4">
          {/* Type selection */}
          <div className="space-y-2">
            <Label>{t('type')}</Label>
            <Select
              value={formData.type}
              onValueChange={(value) =>
                setFormData((prev) => ({ ...prev, type: value as AbsenceType }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder={t('selectType')} />
              </SelectTrigger>
              <SelectContent>
                {absenceTypes.map(([type, info]) => {
                  const Icon = ABSENCE_ICONS[type];
                  return (
                    <SelectItem key={type} value={type}>
                      <div className="flex items-center gap-2">
                        <Icon className={cn('h-4 w-4', info.color)} />
                        <span>{tAbsenceTypes(info.labelKey)}</span>
                      </div>
                    </SelectItem>
                  );
                })}
              </SelectContent>
            </Select>
          </div>

          {/* Date range */}
          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="startDate">{t('startDate')}</Label>
              <div className="relative">
                <CalendarIcon className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  id="startDate"
                  type="date"
                  value={formData.startDate}
                  onChange={(e) => {
                    setFormData((prev) => ({
                      ...prev,
                      startDate: e.target.value,
                      endDate:
                        prev.endDate && e.target.value > prev.endDate
                          ? e.target.value
                          : prev.endDate,
                    }));
                  }}
                  className="pl-10"
                />
              </div>
            </div>
            <div className="space-y-2">
              <Label htmlFor="endDate">{t('endDate')}</Label>
              <div className="relative">
                <CalendarIcon className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  id="endDate"
                  type="date"
                  value={formData.endDate}
                  min={formData.startDate}
                  onChange={(e) =>
                    setFormData((prev) => ({ ...prev, endDate: e.target.value }))
                  }
                  className="pl-10"
                />
              </div>
            </div>
          </div>

          {/* Half day option (only for single day) */}
          {formData.startDate === formData.endDate && (
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <Label htmlFor="halfDay">{t('halfDay')}</Label>
                <Switch
                  id="halfDay"
                  checked={formData.halfDay}
                  onCheckedChange={(checked) =>
                    setFormData((prev) => ({
                      ...prev,
                      halfDay: checked,
                      halfDayPeriod: checked ? 'MORNING' : undefined,
                    }))
                  }
                />
              </div>

              {formData.halfDay && (
                <Select
                  value={formData.halfDayPeriod}
                  onValueChange={(value) =>
                    setFormData((prev) => ({
                      ...prev,
                      halfDayPeriod: value as 'MORNING' | 'AFTERNOON',
                    }))
                  }
                >
                  <SelectTrigger>
                    <SelectValue placeholder={t('selectPeriod')} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="MORNING">{t('morning')}</SelectItem>
                    <SelectItem value="AFTERNOON">{t('afternoon')}</SelectItem>
                  </SelectContent>
                </Select>
              )}
            </div>
          )}

          {/* Days summary */}
          <div className="rounded-lg bg-muted p-4 text-center">
            <p className="text-3xl font-bold">{days}</p>
            <p className="text-sm text-muted-foreground">
              {days === 1 ? t('day') : t('days')}
            </p>
          </div>

          {/* Note */}
          <div className="space-y-2">
            <Label htmlFor="note">{t('note')}</Label>
            <Textarea
              id="note"
              placeholder={t('notePlaceholder')}
              value={formData.note}
              onChange={(e) => setFormData((prev) => ({ ...prev, note: e.target.value }))}
              rows={3}
            />
          </div>

          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={createRequest.isPending}
            >
              {tCommon('cancel')}
            </Button>
            <Button type="submit" disabled={createRequest.isPending || days <= 0} className="gap-2">
              <Send className="h-4 w-4" />
              {t('submitRequest')}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
