'use client';

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

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { DatePicker } from '@/components/ui/date-picker';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { ClientPicker } from '@/components/shared/client-picker';
import { FormErrorSummary } from '@/components/forms/form-error-summary';
import { useFormScrollToError } from '@/hooks/use-form-scroll-to-error';
import { apiFetch } from '@/lib/api/client';
import { ROLES } from '@/lib/validators/company-memberships';

type RoleEnum = (typeof ROLES)[number];

type FormValues = {
  clientId: string | null;
  role: RoleEnum;
  roleDetail?: string;
  startDate: string; // YYYY-MM-DD
  isPrimary: boolean;
  notes?: string;
};

interface AddMembershipDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  companyId: string;
}

const todayIso = (): string => new Date().toISOString().slice(0, 10);

const ROLE_LABEL: Record<RoleEnum, string> = {
  director: 'Director',
  officer: 'Officer',
  broker: 'Broker',
  representative: 'Representative',
  legal_counsel: 'Legal counsel',
  employee: 'Employee',
  shareholder: 'Shareholder',
  other: 'Other',
};

export function AddMembershipDialog({ open, onOpenChange, companyId }: AddMembershipDialogProps) {
  const queryClient = useQueryClient();
  const [formError, setFormError] = useState<string | null>(null);

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    reset,
    control,
    formState: { errors, isSubmitting },
  } = useForm<FormValues>({
    defaultValues: {
      clientId: null,
      role: 'director',
      roleDetail: '',
      startDate: todayIso(),
      isPrimary: false,
      notes: '',
    },
  });
  const submitWithScroll = useFormScrollToError(handleSubmit, errors);

  useEffect(() => {
    if (open) {
      setFormError(null);
      reset({
        clientId: null,
        role: 'director',
        roleDetail: '',
        startDate: todayIso(),
        isPrimary: false,
        notes: '',
      });
    }
  }, [open, reset]);

  const clientId = watch('clientId');
  const role = watch('role');
  const isPrimary = watch('isPrimary');

  const mutation = useMutation({
    mutationFn: async (data: FormValues) => {
      if (!data.clientId) {
        throw new Error('Please select a client');
      }
      await apiFetch(`/api/v1/companies/${companyId}/members`, {
        method: 'POST',
        body: {
          clientId: data.clientId,
          role: data.role,
          roleDetail: data.roleDetail?.trim() || undefined,
          startDate: data.startDate,
          isPrimary: data.isPrimary,
          notes: data.notes?.trim() || undefined,
        },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['companies', companyId, 'members'] });
      onOpenChange(false);
    },
    onError: (err: unknown) => {
      let msg = err instanceof Error ? err.message : 'Failed to add membership';
      // Detect 409 - service returns a "membership already exists" message
      if (/already exists/i.test(msg)) {
        msg = 'This membership already exists (same client + role + start date).';
      }
      setFormError(msg);
    },
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>Add member</DialogTitle>
          <DialogDescription>
            Associate a client with this company in a specific role.
          </DialogDescription>
        </DialogHeader>

        <form
          onSubmit={submitWithScroll((data) => {
            setFormError(null);
            mutation.mutate(data);
          })}
          className="space-y-4"
        >
          <FormErrorSummary
            errors={errors}
            labels={{ clientId: 'Client', role: 'Role', startDate: 'Start date' }}
          />
          <div className="space-y-2">
            <Label>Client</Label>
            <ClientPicker value={clientId} onChange={(id) => setValue('clientId', id)} />
            {!clientId && errors.clientId && <p className="text-xs text-destructive">Required</p>}
          </div>

          <div className="space-y-2">
            <Label>Role</Label>
            <Select value={role} onValueChange={(v) => setValue('role', v as RoleEnum)}>
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {ROLES.map((r) => (
                  <SelectItem key={r} value={r}>
                    {ROLE_LABEL[r]}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <Label htmlFor="roleDetail">Role detail (optional)</Label>
            <Input
              id="roleDetail"
              {...register('roleDetail')}
              placeholder="e.g. Chief Investment Officer"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="startDate">Start date</Label>
            <Controller
              control={control}
              name="startDate"
              rules={{ required: true }}
              render={({ field }) => (
                <DatePicker id="startDate" value={field.value ?? ''} onChange={field.onChange} />
              )}
            />
            {errors.startDate && <p className="text-xs text-destructive">Required</p>}
          </div>

          <div className="flex items-center gap-2">
            <Checkbox
              id="isPrimary"
              checked={isPrimary}
              onCheckedChange={(v) => setValue('isPrimary', v === true)}
            />
            <Label htmlFor="isPrimary" className="cursor-pointer">
              Set as primary contact
            </Label>
          </div>

          <div className="space-y-2">
            <Label htmlFor="notes">Notes (optional)</Label>
            <Textarea id="notes" rows={2} {...register('notes')} />
          </div>

          {formError && <p className="text-sm text-destructive">{formError}</p>}

          <DialogFooter>
            <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" aria-hidden />
              )}
              Add member
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
