'use client';

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

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter } from '@/components/ui/sheet';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { Checkbox } from '@/components/ui/checkbox';
import { Separator } from '@/components/ui/separator';
import { TagPicker } from '@/components/shared/tag-picker';
import { YachtForm } from '@/components/yachts/yacht-form';
import { YachtPicker } from '@/components/yachts/yacht-picker';
import { apiFetch } from '@/lib/api/client';
import { useEntityOptions } from '@/hooks/use-entity-options';
import { createInterestSchema, type CreateInterestInput } from '@/lib/validators/interests';
import { PIPELINE_STAGES, STAGE_LABELS, LEAD_CATEGORIES } from '@/lib/constants';
import { cn } from '@/lib/utils';

const CATEGORY_LABELS: Record<string, string> = {
  general_interest: 'General Interest',
  specific_qualified: 'Specific Qualified',
  hot_lead: 'Hot Lead',
};

interface InterestFormProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /**
   * Pre-fill clientId when launching the form from a client detail page.
   * Ignored when `interest` is provided (edit mode).
   */
  defaultClientId?: string;
  interest?: {
    id: string;
    clientId: string;
    clientName?: string | null;
    yachtId?: string | null;
    berthId?: string | null;
    berthMooringNumber?: string | null;
    pipelineStage: string;
    leadCategory?: string | null;
    source?: string | null;
    reminderEnabled?: boolean;
    reminderDays?: number | null;
    tags?: Array<{ id: string }>;
    desiredLengthFt?: string | number | null;
    desiredWidthFt?: string | number | null;
    desiredDraftFt?: string | number | null;
  };
}

export function InterestForm({ open, onOpenChange, defaultClientId, interest }: InterestFormProps) {
  const queryClient = useQueryClient();
  const isEdit = !!interest;

  const [clientOpen, setClientOpen] = useState(false);
  const [berthOpen, setBerthOpen] = useState(false);

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    reset,
    formState: { errors, isSubmitting },
  } = useForm<CreateInterestInput>({
    resolver: zodResolver(createInterestSchema),
    defaultValues: {
      clientId: '',
      yachtId: undefined,
      pipelineStage: 'open',
      reminderEnabled: false,
      tagIds: [],
    },
  });

  const tagIds = watch('tagIds') ?? [];
  const reminderEnabled = watch('reminderEnabled');
  const selectedClientId = watch('clientId');
  const selectedBerthId = watch('berthId');
  const selectedYachtId = watch('yachtId');
  const [createYachtOpen, setCreateYachtOpen] = useState(false);

  // Fetch the selected client's company memberships so the YachtPicker can
  // include yachts owned by companies the client belongs to (e.g. a
  // managing-director client whose yachts are titled to the company).
  const { data: clientDetail } = useQuery<{
    data: { companies?: Array<{ company: { id: string } }> };
  }>({
    queryKey: ['client-detail-for-interest-form', selectedClientId],
    queryFn: () => apiFetch(`/api/v1/clients/${selectedClientId}`),
    enabled: !!selectedClientId,
  });
  const memberCompanyIds: string[] = clientDetail?.data.companies?.map((m) => m.company.id) ?? [];
  const yachtOwnerFilter = selectedClientId
    ? [
        { type: 'client' as const, id: selectedClientId },
        ...memberCompanyIds.map((id) => ({ type: 'company' as const, id })),
      ]
    : undefined;

  const {
    options: clientOptions,
    isLoading: clientsLoading,
    setSearch: setClientSearch,
  } = useEntityOptions({
    endpoint: '/api/v1/clients/options',
    labelKey: 'fullName',
  });

  const {
    options: berthOptions,
    isLoading: berthsLoading,
    setSearch: setBerthSearch,
  } = useEntityOptions({
    endpoint: '/api/v1/berths/options',
    labelKey: 'mooringNumber',
  });

  useEffect(() => {
    if (interest && open) {
      reset({
        clientId: interest.clientId,
        yachtId: interest.yachtId ?? undefined,
        berthId: interest.berthId ?? undefined,
        pipelineStage: interest.pipelineStage as (typeof PIPELINE_STAGES)[number],
        leadCategory: interest.leadCategory as (typeof LEAD_CATEGORIES)[number] | undefined,
        source: interest.source ?? undefined,
        reminderEnabled: interest.reminderEnabled ?? false,
        reminderDays: interest.reminderDays ?? undefined,
        tagIds: interest.tags?.map((t) => t.id) ?? [],
        desiredLengthFt:
          interest.desiredLengthFt === null || interest.desiredLengthFt === undefined
            ? undefined
            : String(interest.desiredLengthFt),
        desiredWidthFt:
          interest.desiredWidthFt === null || interest.desiredWidthFt === undefined
            ? undefined
            : String(interest.desiredWidthFt),
        desiredDraftFt:
          interest.desiredDraftFt === null || interest.desiredDraftFt === undefined
            ? undefined
            : String(interest.desiredDraftFt),
      });
    } else if (!interest && open) {
      reset({
        clientId: defaultClientId ?? '',
        yachtId: undefined,
        pipelineStage: 'open',
        reminderEnabled: false,
        tagIds: [],
      });
    }
  }, [interest, defaultClientId, open, reset]);

  const mutation = useMutation({
    mutationFn: async (data: CreateInterestInput) => {
      if (isEdit) {
        const { tagIds: tIds, ...rest } = data;
        await apiFetch(`/api/v1/interests/${interest!.id}`, { method: 'PATCH', body: rest });
        if (tIds) {
          await apiFetch(`/api/v1/interests/${interest!.id}/tags`, {
            method: 'PUT',
            body: { tagIds: tIds },
          });
        }
      } else {
        await apiFetch('/api/v1/interests', { method: 'POST', body: data });
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['interests'] });
      onOpenChange(false);
    },
  });

  const selectedClient = clientOptions.find((c) => c.value === selectedClientId);
  const selectedBerth = berthOptions.find((b) => b.value === selectedBerthId);

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

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

            <div className="space-y-1">
              <Label>Client *</Label>
              <Popover open={clientOpen} onOpenChange={setClientOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={clientOpen}
                    className={cn(
                      'w-full justify-between',
                      !selectedClientId && 'text-muted-foreground',
                    )}
                    disabled={isEdit}
                  >
                    {selectedClient?.label ?? interest?.clientName ?? 'Select client...'}
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[400px] p-0">
                  <Command>
                    <CommandInput placeholder="Search clients..." onValueChange={setClientSearch} />
                    <CommandList>
                      <CommandEmpty>
                        {clientsLoading ? 'Loading...' : 'No clients found.'}
                      </CommandEmpty>
                      <CommandGroup>
                        {clientOptions.map((option) => (
                          <CommandItem
                            key={option.value}
                            value={option.value}
                            onSelect={(val) => {
                              setValue('clientId', val);
                              setClientOpen(false);
                            }}
                          >
                            <Check
                              className={cn(
                                'mr-2 h-4 w-4',
                                selectedClientId === option.value ? 'opacity-100' : 'opacity-0',
                              )}
                            />
                            {option.label}
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
              {errors.clientId && (
                <p className="text-xs text-destructive">{errors.clientId.message}</p>
              )}
            </div>

            <div className="space-y-1">
              <Label>Berth (optional)</Label>
              <Popover open={berthOpen} onOpenChange={setBerthOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={berthOpen}
                    className={cn(
                      'w-full justify-between',
                      !selectedBerthId && 'text-muted-foreground',
                    )}
                  >
                    {selectedBerth?.label ?? interest?.berthMooringNumber ?? 'Select berth...'}
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[400px] p-0">
                  <Command>
                    <CommandInput placeholder="Search berths..." onValueChange={setBerthSearch} />
                    <CommandList>
                      <CommandEmpty>
                        {berthsLoading ? 'Loading...' : 'No berths found.'}
                      </CommandEmpty>
                      <CommandGroup>
                        <CommandItem
                          value=""
                          onSelect={() => {
                            setValue('berthId', undefined);
                            setBerthOpen(false);
                          }}
                        >
                          <Check
                            className={cn(
                              'mr-2 h-4 w-4',
                              !selectedBerthId ? 'opacity-100' : 'opacity-0',
                            )}
                          />
                          None
                        </CommandItem>
                        {berthOptions.map((option) => (
                          <CommandItem
                            key={option.value}
                            value={option.value}
                            onSelect={(val) => {
                              setValue('berthId', val);
                              setBerthOpen(false);
                            }}
                          >
                            <Check
                              className={cn(
                                'mr-2 h-4 w-4',
                                selectedBerthId === option.value ? 'opacity-100' : 'opacity-0',
                              )}
                            />
                            {option.label}
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>

            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label>Yacht</Label>
                {selectedClientId && (
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    className="h-7 text-xs"
                    onClick={() => setCreateYachtOpen(true)}
                  >
                    <Plus className="mr-1 h-3 w-3" />
                    Add new
                  </Button>
                )}
              </div>
              <YachtPicker
                value={selectedYachtId ?? null}
                onChange={(id) => setValue('yachtId', id ?? undefined)}
                ownerFilter={yachtOwnerFilter}
                disabled={!selectedClientId}
                placeholder={selectedClientId ? 'Select yacht...' : 'Select a client first'}
              />
              <p className="text-xs text-muted-foreground">
                Required before the interest can leave the &quot;Open&quot; stage.
                {memberCompanyIds.length > 0 && (
                  <>
                    {' '}
                    Includes yachts from {memberCompanyIds.length}{' '}
                    {memberCompanyIds.length === 1 ? 'member company' : 'member companies'}.
                  </>
                )}
              </p>
            </div>
          </div>

          <Separator />

          {/* Pipeline */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Pipeline
            </h3>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Stage</Label>
                <Select
                  value={watch('pipelineStage') ?? 'open'}
                  onValueChange={(v) =>
                    setValue('pipelineStage', v as (typeof PIPELINE_STAGES)[number])
                  }
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select stage" />
                  </SelectTrigger>
                  <SelectContent>
                    {PIPELINE_STAGES.map((s) => (
                      <SelectItem key={s} value={s}>
                        {STAGE_LABELS[s]}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-1">
                <Label>Lead Category</Label>
                <Select
                  value={watch('leadCategory') ?? ''}
                  onValueChange={(v) =>
                    setValue(
                      'leadCategory',
                      v ? (v as (typeof LEAD_CATEGORIES)[number]) : undefined,
                    )
                  }
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select category" />
                  </SelectTrigger>
                  <SelectContent>
                    {LEAD_CATEGORIES.map((c) => (
                      <SelectItem key={c} value={c}>
                        {CATEGORY_LABELS[c] ?? c}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-1">
                <Label>Source</Label>
                <Select
                  value={watch('source') ?? ''}
                  onValueChange={(v) => setValue('source', v || undefined)}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select source" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="website">Website</SelectItem>
                    <SelectItem value="manual">Manual</SelectItem>
                    <SelectItem value="referral">Referral</SelectItem>
                    <SelectItem value="broker">Broker</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
          </div>

          <Separator />

          {/* Desired berth dimensions (recommender inputs) */}
          <div className="space-y-2">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Berth size desired
            </h3>
            <p className="text-xs text-muted-foreground">
              Imperial. Optional - the recommender treats blank fields as no constraint on that
              axis.
            </p>
            <div className="grid grid-cols-3 gap-3">
              <div className="space-y-1">
                <Label htmlFor="desiredLengthFt">Length (ft)</Label>
                <Input
                  id="desiredLengthFt"
                  {...register('desiredLengthFt')}
                  type="number"
                  step="0.01"
                  min={0}
                  placeholder="e.g. 60"
                />
              </div>
              <div className="space-y-1">
                <Label htmlFor="desiredWidthFt">Width (ft)</Label>
                <Input
                  id="desiredWidthFt"
                  {...register('desiredWidthFt')}
                  type="number"
                  step="0.01"
                  min={0}
                  placeholder="e.g. 18"
                />
              </div>
              <div className="space-y-1">
                <Label htmlFor="desiredDraftFt">Draft (ft)</Label>
                <Input
                  id="desiredDraftFt"
                  {...register('desiredDraftFt')}
                  type="number"
                  step="0.01"
                  min={0}
                  placeholder="e.g. 6"
                />
              </div>
            </div>
          </div>

          <Separator />

          {/* Reminder */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Reminder
            </h3>
            <div className="flex items-center gap-2">
              <Checkbox
                id="reminderEnabled"
                checked={reminderEnabled ?? false}
                onCheckedChange={(v) => setValue('reminderEnabled', !!v)}
              />
              <Label htmlFor="reminderEnabled">Enable reminder</Label>
            </div>
            {reminderEnabled && (
              <div className="space-y-1">
                <Label>Reminder Days</Label>
                <Input
                  {...register('reminderDays', { valueAsNumber: true })}
                  type="number"
                  min={1}
                  placeholder="e.g. 7"
                />
              </div>
            )}
          </div>

          <Separator />

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

          <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 Interest'}
            </Button>
          </SheetFooter>
        </form>
      </SheetContent>
      {createYachtOpen && selectedClientId && (
        <YachtForm
          open={createYachtOpen}
          onOpenChange={setCreateYachtOpen}
          initialOwner={{ type: 'client', id: selectedClientId }}
        />
      )}
    </Sheet>
  );
}
