'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 { z } from 'zod';

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, SheetFooter, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { Separator } from '@/components/ui/separator';
import { TagPicker } from '@/components/shared/tag-picker';
import { CountryCombobox } from '@/components/shared/country-combobox';
import { SubdivisionCombobox } from '@/components/shared/subdivision-combobox';
import { apiFetch } from '@/lib/api/client';
import { createCompanySchema, type CreateCompanyInput } from '@/lib/validators/companies';
import type { CountryCode } from '@/lib/i18n/countries';

type CompanyStatus = 'active' | 'dissolved';

type CompanyFormValues = z.input<typeof createCompanySchema>;

interface CompanyFormProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** If provided, form is in edit mode */
  company?: {
    id: string;
    name: string;
    legalName: string | null;
    taxId: string | null;
    registrationNumber: string | null;
    incorporationCountryIso: string | null;
    incorporationSubdivisionIso: string | null;
    incorporationDate: string | null;
    status: string;
    billingEmail: string | null;
    notes: string | null;
  };
}

export function CompanyForm({ open, onOpenChange, company }: CompanyFormProps) {
  const queryClient = useQueryClient();
  const isEdit = !!company;
  const [formError, setFormError] = useState<string | null>(null);

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

  const tagIds = watch('tagIds') ?? [];
  const status = watch('status') ?? 'active';

  // Populate form when editing, or reset to defaults in create mode.
  useEffect(() => {
    if (company && open) {
      reset({
        name: company.name,
        legalName: company.legalName ?? undefined,
        taxId: company.taxId ?? undefined,
        registrationNumber: company.registrationNumber ?? undefined,
        incorporationCountryIso: company.incorporationCountryIso ?? undefined,
        incorporationSubdivisionIso: company.incorporationSubdivisionIso ?? undefined,
        incorporationDate: company.incorporationDate
          ? new Date(company.incorporationDate)
          : undefined,
        status: (company.status as CompanyStatus) ?? 'active',
        billingEmail: company.billingEmail ?? undefined,
        notes: company.notes ?? undefined,
        tagIds: [],
      });
    } else if (!company && open) {
      reset({ name: '', status: 'active', tagIds: [] });
    }
    setFormError(null);
  }, [company, open, reset]);

  const mutation = useMutation({
    mutationFn: async (data: CreateCompanyInput) => {
      if (isEdit) {
        // updateCompanySchema omits tagIds — strip them from PATCH body.
        const { tagIds: _tIds, ...rest } = data;
        void _tIds;
        await apiFetch(`/api/v1/companies/${company!.id}`, {
          method: 'PATCH',
          body: rest,
        });
      } else {
        await apiFetch('/api/v1/companies', { method: 'POST', body: data });
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['companies'] });
      onOpenChange(false);
    },
    onError: (err: unknown) => {
      const msg = err instanceof Error ? err.message : 'Failed to save company';
      setFormError(msg);
    },
  });

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

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

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

              <div className="col-span-2 space-y-1">
                <Label>Legal Name</Label>
                <Input {...register('legalName')} placeholder="Acme Holdings Limited" />
              </div>
            </div>
          </div>

          <Separator />

          {/* Registration */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Registration
            </h3>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Tax ID</Label>
                <Input {...register('taxId')} placeholder="VAT / EIN" />
              </div>
              <div className="space-y-1">
                <Label>Registration Number</Label>
                <Input {...register('registrationNumber')} placeholder="Company #" />
              </div>
              <div className="space-y-1">
                <Label>Incorporation Country</Label>
                <CountryCombobox
                  value={watch('incorporationCountryIso')}
                  onChange={(iso) => {
                    setValue('incorporationCountryIso', iso ?? undefined);
                    // Wipe subdivision when country flips — codes are country-scoped.
                    setValue('incorporationSubdivisionIso', undefined);
                  }}
                  data-testid="company-incorp-country"
                />
              </div>
              <div className="space-y-1">
                <Label>Incorporation Region</Label>
                <SubdivisionCombobox
                  value={watch('incorporationSubdivisionIso')}
                  onChange={(code) => setValue('incorporationSubdivisionIso', code ?? undefined)}
                  country={(watch('incorporationCountryIso') as CountryCode | undefined) ?? null}
                  data-testid="company-incorp-subdivision"
                />
              </div>
              <div className="space-y-1">
                <Label>Incorporation Date</Label>
                <Input type="date" {...register('incorporationDate')} />
                {errors.incorporationDate && (
                  <p className="text-xs text-destructive">{errors.incorporationDate.message}</p>
                )}
              </div>
            </div>
          </div>

          <Separator />

          {/* Contact & Status */}
          <div className="space-y-4">
            <h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
              Contact & Status
            </h3>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Billing Email</Label>
                <Input
                  type="email"
                  {...register('billingEmail')}
                  placeholder="billing@example.com"
                />
                {errors.billingEmail && (
                  <p className="text-xs text-destructive">{errors.billingEmail.message}</p>
                )}
              </div>
              <div className="space-y-1">
                <Label>Status</Label>
                <Select
                  value={status}
                  onValueChange={(v) => setValue('status', v as CompanyStatus)}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select status" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="active">Active</SelectItem>
                    <SelectItem value="dissolved">Dissolved</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
          </div>

          <Separator />

          {/* Notes */}
          <div className="space-y-2">
            <Label>Notes</Label>
            <Textarea
              {...register('notes')}
              placeholder="Internal notes about this company"
              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 Company'}
            </Button>
          </SheetFooter>
        </form>
      </SheetContent>
    </Sheet>
  );
}
