'use client';

import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Loader2 } from 'lucide-react';

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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter } from '@/components/ui/sheet';
import { Separator } from '@/components/ui/separator';
import { OwnerPicker, type OwnerRef } from '@/components/shared/owner-picker';
import { TagPicker } from '@/components/shared/tag-picker';
import { apiFetch } from '@/lib/api/client';
import { createYachtSchema, type CreateYachtInput } from '@/lib/validators/yachts';

interface YachtFormProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** If provided, form is in edit mode */
  yacht?: {
    id: string;
    name: string;
    hullNumber?: string | null;
    registration?: string | null;
    flag?: string | null;
    yearBuilt?: number | null;
    builder?: string | null;
    model?: string | null;
    hullMaterial?: string | null;
    lengthFt?: string | null;
    widthFt?: string | null;
    draftFt?: string | null;
    lengthM?: string | null;
    widthM?: string | null;
    draftM?: string | null;
    currentOwnerType: 'client' | 'company';
    currentOwnerId: string;
    status?: string | null;
    notes?: string | null;
  };
  /**
   * In create mode, pre-select the owner so a user opening this form from
   * a client/company detail page doesn't have to manually re-pick the
   * entity they're already on. Ignored in edit mode (the existing
   * owner-history workflow is the right surface for ownership changes).
   */
  initialOwner?: { type: 'client' | 'company'; id: string };
}

type YachtStatus = 'active' | 'retired' | 'sold_away';

export function YachtForm({ open, onOpenChange, yacht, initialOwner }: YachtFormProps) {
  const queryClient = useQueryClient();
  const isEdit = !!yacht;
  const [formError, setFormError] = useState<string | null>(null);

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    reset,
    formState: { errors, isSubmitting },
  } = useForm<CreateYachtInput>({
    resolver: zodResolver(createYachtSchema),
    defaultValues: {
      name: '',
      status: 'active',
      tagIds: [],
    },
  });

  const tagIds = watch('tagIds') ?? [];
  const owner = watch('owner') as OwnerRef | undefined;
  const status = watch('status') ?? 'active';

  // Populate form when editing, or reset to defaults in create mode.
  useEffect(() => {
    if (yacht && open) {
      reset({
        name: yacht.name,
        hullNumber: yacht.hullNumber ?? undefined,
        registration: yacht.registration ?? undefined,
        flag: yacht.flag ?? undefined,
        yearBuilt: yacht.yearBuilt ?? undefined,
        builder: yacht.builder ?? undefined,
        model: yacht.model ?? undefined,
        hullMaterial: yacht.hullMaterial ?? undefined,
        lengthFt: yacht.lengthFt ?? undefined,
        widthFt: yacht.widthFt ?? undefined,
        draftFt: yacht.draftFt ?? undefined,
        lengthM: yacht.lengthM ?? undefined,
        widthM: yacht.widthM ?? undefined,
        draftM: yacht.draftM ?? undefined,
        // Owner is required by the schema in create mode. In edit mode we
        // strip it before PATCH, but we still satisfy the resolver by
        // supplying the current owner.
        owner: { type: yacht.currentOwnerType, id: yacht.currentOwnerId },
        status: (yacht.status as YachtStatus | null) ?? 'active',
        notes: yacht.notes ?? undefined,
        tagIds: [],
      });
    } else if (!yacht && open) {
      reset({
        name: '',
        status: 'active',
        tagIds: [],
        ...(initialOwner ? { owner: initialOwner } : {}),
      });
    }
    setFormError(null);
  }, [yacht, open, reset, initialOwner]);

  const mutation = useMutation({
    mutationFn: async (data: CreateYachtInput) => {
      if (isEdit) {
        // updateYachtSchema omits owner + tagIds - strip them from PATCH body.
        const { owner: _owner, tagIds: _tIds, ...rest } = data;
        void _owner;
        void _tIds;
        await apiFetch(`/api/v1/yachts/${yacht!.id}`, {
          method: 'PATCH',
          body: rest,
        });
      } else {
        await apiFetch('/api/v1/yachts', { method: 'POST', body: data });
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['yachts'] });
      onOpenChange(false);
    },
    onError: (err: Error) => {
      setFormError(err.message || 'Failed to save yacht');
    },
  });

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="w-full sm:max-w-2xl overflow-y-auto">
        <SheetHeader>
          <SheetTitle>{isEdit ? 'Edit Yacht' : 'New Yacht'}</SheetTitle>
        </SheetHeader>

        <form
          onSubmit={handleSubmit((data) => {
            setFormError(null);
            mutation.mutate(data);
          })}
          className="space-y-6 py-6"
        >
          {/* Basic */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Basic
            </h3>

            <div className="grid grid-cols-2 gap-4">
              <div className="col-span-2 space-y-1">
                <Label>Name *</Label>
                <Input {...register('name')} placeholder="Sea Breeze" />
                {errors.name && <p className="text-xs text-destructive">{errors.name.message}</p>}
              </div>

              <div className="space-y-1">
                <Label>Hull Number</Label>
                <Input {...register('hullNumber')} placeholder="HIN" />
              </div>

              <div className="space-y-1">
                <Label>Registration</Label>
                <Input {...register('registration')} placeholder="Registration #" />
              </div>

              <div className="space-y-1">
                <Label>Flag</Label>
                <Input {...register('flag')} placeholder="e.g. MT" />
              </div>

              <div className="space-y-1">
                <Label>Year Built</Label>
                <Input
                  type="number"
                  {...register('yearBuilt', { valueAsNumber: true })}
                  placeholder="2015"
                />
                {errors.yearBuilt && (
                  <p className="text-xs text-destructive">{errors.yearBuilt.message}</p>
                )}
              </div>
            </div>
          </div>

          <Separator />

          {/* Build */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Build
            </h3>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Builder</Label>
                <Input {...register('builder')} placeholder="Benetti" />
              </div>
              <div className="space-y-1">
                <Label>Model</Label>
                <Input {...register('model')} placeholder="Classic 120" />
              </div>
              <div className="col-span-2 space-y-1">
                <Label>Hull Material</Label>
                <Input {...register('hullMaterial')} placeholder="Aluminium" />
              </div>
            </div>
          </div>

          <Separator />

          {/* Dimensions (ft) */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Dimensions (ft)
            </h3>
            <div className="grid grid-cols-3 gap-4">
              <div className="space-y-1">
                <Label>Length (ft)</Label>
                <Input {...register('lengthFt')} placeholder="120" />
              </div>
              <div className="space-y-1">
                <Label>Width (ft)</Label>
                <Input {...register('widthFt')} placeholder="25" />
              </div>
              <div className="space-y-1">
                <Label>Draft (ft)</Label>
                <Input {...register('draftFt')} placeholder="8" />
              </div>
            </div>
          </div>

          <Separator />

          {/* Dimensions (m) */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Dimensions (m)
            </h3>
            <div className="grid grid-cols-3 gap-4">
              <div className="space-y-1">
                <Label>Length (m)</Label>
                <Input {...register('lengthM')} placeholder="36.5" />
              </div>
              <div className="space-y-1">
                <Label>Width (m)</Label>
                <Input {...register('widthM')} placeholder="7.6" />
              </div>
              <div className="space-y-1">
                <Label>Draft (m)</Label>
                <Input {...register('draftM')} placeholder="2.4" />
              </div>
            </div>
          </div>

          <Separator />

          {/* Ownership */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Ownership
            </h3>

            {isEdit ? (
              <p className="rounded-md border bg-muted/30 px-3 py-2 text-xs text-muted-foreground">
                Ownership changes use the Transfer button.
              </p>
            ) : (
              <div className="space-y-1">
                <Label>Owner *</Label>
                <OwnerPicker
                  value={owner ?? null}
                  onChange={(v) => {
                    if (v) {
                      setValue('owner', v, { shouldValidate: true });
                    }
                  }}
                />
                {errors.owner && (
                  <p className="text-xs text-destructive">
                    {errors.owner.message ?? 'Owner is required'}
                  </p>
                )}
              </div>
            )}
          </div>

          <Separator />

          {/* Status */}
          <div className="space-y-2">
            <Label>Status</Label>
            <Select value={status} onValueChange={(v) => setValue('status', v as YachtStatus)}>
              <SelectTrigger>
                <SelectValue placeholder="Select status" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="active">Active</SelectItem>
                <SelectItem value="retired">Retired</SelectItem>
                <SelectItem value="sold_away">Sold away</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <Separator />

          {/* Notes */}
          <div className="space-y-2">
            <Label>Notes</Label>
            <Textarea
              {...register('notes')}
              placeholder="Internal notes about this yacht"
              rows={4}
            />
          </div>

          <Separator />

          {/* Tags */}
          <div className="space-y-2">
            <Label>Tags</Label>
            <TagPicker selectedIds={tagIds} onChange={(ids) => setValue('tagIds', ids)} />
          </div>

          {formError && (
            <p className="text-sm text-destructive" role="alert">
              {formError}
            </p>
          )}

          <SheetFooter>
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type="submit" disabled={isSubmitting || mutation.isPending}>
              {(isSubmitting || mutation.isPending) && (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              )}
              {isEdit ? 'Save Changes' : 'Create Yacht'}
            </Button>
          </SheetFooter>
        </form>
      </SheetContent>
    </Sheet>
  );
}
