import { useState, useMemo, FormEvent } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Star, StarOff, X } from 'lucide-react';
import { parseISO, differenceInYears } from 'date-fns';
import api, { getErrorMessage } from '@/lib/api';
import type { Person } from '@/types';
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetFooter,
} from '@/components/ui/sheet';
import { Input } from '@/components/ui/input';
import { DatePicker } from '@/components/ui/date-picker';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import LocationPicker from '@/components/ui/location-picker';
import CategoryAutocomplete from '@/components/shared/CategoryAutocomplete';
import { splitName } from '@/components/shared/utils';

interface PersonFormProps {
  person: Person | null;
  categories: string[];
  onClose: () => void;
}

export default function PersonForm({ person, categories, onClose }: PersonFormProps) {
  const queryClient = useQueryClient();

  const [formData, setFormData] = useState({
    first_name:
      person?.first_name ||
      (person?.name ? splitName(person.name).firstName : ''),
    last_name:
      person?.last_name ||
      (person?.name ? splitName(person.name).lastName : ''),
    nickname: person?.nickname || '',
    email: person?.email || '',
    phone: person?.phone || '',
    mobile: person?.mobile || '',
    address: person?.address || '',
    birthday: person?.birthday
      ? person.birthday.slice(0, 10)
      : '',
    category: person?.category || '',
    is_favourite: person?.is_favourite ?? false,
    company: person?.company || '',
    job_title: person?.job_title || '',
    notes: person?.notes || '',
  });

  const age = useMemo(() => {
    if (!formData.birthday) return null;
    try {
      return differenceInYears(new Date(), parseISO(formData.birthday));
    } catch {
      return null;
    }
  }, [formData.birthday]);

  const set = <K extends keyof typeof formData>(key: K, value: (typeof formData)[K]) => {
    setFormData((prev) => ({ ...prev, [key]: value }));
  };

  const mutation = useMutation({
    mutationFn: async (data: typeof formData) => {
      if (person) {
        const { data: res } = await api.put(`/people/${person.id}`, data);
        return res;
      }
      const { data: res } = await api.post('/people', data);
      return res;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['people'] });
      queryClient.invalidateQueries({ queryKey: ['dashboard'] });
      queryClient.invalidateQueries({ queryKey: ['upcoming'] });
      toast.success(person ? 'Person updated' : 'Person created');
      onClose();
    },
    onError: (error) => {
      toast.error(
        getErrorMessage(error, person ? 'Failed to update person' : 'Failed to create person')
      );
    },
  });

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    mutation.mutate({ ...formData, birthday: formData.birthday || null } as typeof formData);
  };

  return (
    <Sheet open={true} onOpenChange={onClose}>
      <SheetContent>
        <SheetHeader>
          <div className="flex items-center justify-between">
            <SheetTitle>{person ? 'Edit Person' : 'New Person'}</SheetTitle>
            <div className="flex items-center gap-1">
              <Button
                type="button"
                variant="ghost"
                size="icon"
                className={`h-7 w-7 ${formData.is_favourite ? 'text-yellow-400' : 'text-muted-foreground'}`}
                onClick={() => set('is_favourite', !formData.is_favourite)}
                aria-label={formData.is_favourite ? 'Remove from favourites' : 'Add to favourites'}
              >
                {formData.is_favourite ? (
                  <Star className="h-4 w-4 fill-yellow-400" />
                ) : (
                  <StarOff className="h-4 w-4" />
                )}
              </Button>
              <Button
                type="button"
                variant="ghost"
                size="icon"
                onClick={onClose}
                aria-label="Close"
                className="h-7 w-7 shrink-0"
              >
                <X className="h-4 w-4" />
              </Button>
            </div>
          </div>
        </SheetHeader>

        <form onSubmit={handleSubmit} className="flex flex-col flex-1 overflow-y-auto">
          <div className="px-6 py-5 space-y-4 flex-1">
            {/* Row 2: First + Last name */}
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="first_name" required>First Name</Label>
                <Input
                  id="first_name"
                  value={formData.first_name}
                  onChange={(e) => set('first_name', e.target.value)}
                  required
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="last_name">Last Name</Label>
                <Input
                  id="last_name"
                  value={formData.last_name}
                  onChange={(e) => set('last_name', e.target.value)}
                />
              </div>
            </div>

            {/* Row 3: Nickname */}
            <div className="space-y-2">
              <Label htmlFor="nickname">Nickname</Label>
              <Input
                id="nickname"
                value={formData.nickname}
                onChange={(e) => set('nickname', e.target.value)}
                placeholder="Optional display name"
              />
            </div>

            {/* Row 4: Birthday + Age */}
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="birthday">Birthday</Label>
                <DatePicker
                  variant="input"
                  id="birthday"
                  value={formData.birthday}
                  onChange={(v) => set('birthday', v)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="age">Age</Label>
                <Input
                  id="age"
                  value={age !== null ? String(age) : ''}
                  disabled
                  placeholder="—"
                  aria-label="Calculated age"
                />
              </div>
            </div>

            {/* Row 5: Category */}
            <div className="space-y-2">
              <Label htmlFor="category">Category</Label>
              <CategoryAutocomplete
                id="category"
                value={formData.category}
                onChange={(val) => set('category', val)}
                categories={categories}
                placeholder="e.g. Friend, Family, Colleague"
              />
            </div>

            {/* Row 6: Mobile + Email */}
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="mobile">Mobile</Label>
                <Input
                  id="mobile"
                  type="tel"
                  value={formData.mobile}
                  onChange={(e) => set('mobile', e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="email">Email</Label>
                <Input
                  id="email"
                  type="email"
                  value={formData.email}
                  onChange={(e) => set('email', e.target.value)}
                />
              </div>
            </div>

            {/* Row 7: Phone */}
            <div className="space-y-2">
              <Label htmlFor="phone">Phone</Label>
              <Input
                id="phone"
                type="tel"
                value={formData.phone}
                onChange={(e) => set('phone', e.target.value)}
                placeholder="Landline / work number"
              />
            </div>

            {/* Row 8: Address */}
            <div className="space-y-2">
              <Label htmlFor="address">Address</Label>
              <LocationPicker
                id="address"
                value={formData.address}
                onChange={(val) => set('address', val)}
                onSelect={(result) => set('address', result.address || result.name)}
                placeholder="Search or enter address..."
              />
            </div>

            {/* Row 9: Company + Job Title */}
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="company">Company</Label>
                <Input
                  id="company"
                  value={formData.company}
                  onChange={(e) => set('company', e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="job_title">Job Title</Label>
                <Input
                  id="job_title"
                  value={formData.job_title}
                  onChange={(e) => set('job_title', e.target.value)}
                />
              </div>
            </div>

            {/* Row 10: Notes */}
            <div className="space-y-2">
              <Label htmlFor="notes">Notes</Label>
              <Textarea
                id="notes"
                value={formData.notes}
                onChange={(e) => set('notes', e.target.value)}
                rows={3}
                placeholder="Any additional context..."
              />
            </div>
          </div>

          <SheetFooter>
            <Button type="button" variant="outline" onClick={onClose}>
              Cancel
            </Button>
            <Button type="submit" disabled={mutation.isPending}>
              {mutation.isPending ? 'Saving...' : person ? 'Update' : 'Create'}
            </Button>
          </SheetFooter>
        </form>
      </SheetContent>
    </Sheet>
  );
}
