'use client';

import { useEffect, useState } from 'react';
import { useParams, useRouter, useSearchParams } from 'next/navigation';
import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQuery } from '@tanstack/react-query';
import { ChevronLeft, ChevronRight, Check, Loader2, Wallet } from 'lucide-react';

import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';

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 { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { OwnerPicker } from '@/components/shared/owner-picker';
import { CurrencySelect } from '@/components/shared/currency-select';
import { InvoiceLineItems } from '@/components/invoices/invoice-line-items';
import { FormErrorSummary } from '@/components/forms/form-error-summary';
import { useFormScrollToError } from '@/hooks/use-form-scroll-to-error';
import { apiFetch } from '@/lib/api/client';
import { formatCurrency } from '@/lib/utils/currency';
import type { z } from 'zod';
import { createInvoiceSchema, type CreateInvoiceInput } from '@/lib/validators/invoices';

const PAYMENT_TERMS = [
  { label: 'Immediate', value: 'immediate' },
  { label: 'Net 10', value: 'net10' },
  { label: 'Net 15', value: 'net15' },
  { label: 'Net 30', value: 'net30' },
  { label: 'Net 45', value: 'net45' },
  { label: 'Net 60', value: 'net60' },
];

const STEPS = [
  { id: 1, label: 'Client Info' },
  { id: 2, label: 'Line Items' },
  { id: 3, label: 'Review' },
];

export default function NewInvoicePage() {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const router = useRouter();
  const searchParams = useSearchParams();
  const prefilledInterestId = searchParams.get('interestId') ?? undefined;
  const prefilledKind =
    searchParams.get('kind') === 'deposit' ? ('deposit' as const) : ('general' as const);

  const [step, setStep] = useState(1);

  const { setChrome } = useMobileChrome();
  useEffect(() => {
    setChrome({ title: 'New Invoice', showBackButton: true });
    return () => setChrome({ title: null, showBackButton: false });
  }, [setChrome]);

  // When the form is launched from an interest detail with `?interestId=…&kind=deposit`,
  // fetch enough of the interest to display "Deposit for {client} - Berth {n}" in
  // the review step. Doubles as the source of truth for the billing entity prefill.
  const { data: prefilledInterest } = useQuery<{
    data: {
      id: string;
      clientId: string;
      clientName: string | null;
      berthMooringNumber: string | null;
    };
  }>({
    queryKey: ['interest-prefill', prefilledInterestId],
    queryFn: () => apiFetch(`/api/v1/interests/${prefilledInterestId}`),
    enabled: !!prefilledInterestId,
  });

  const methods = useForm<z.input<typeof createInvoiceSchema>, unknown, CreateInvoiceInput>({
    resolver: zodResolver(createInvoiceSchema),
    defaultValues: {
      paymentTerms: 'net30',
      currency: 'USD',
      lineItems: [],
      expenseIds: [],
      interestId: prefilledInterestId,
      kind: prefilledKind,
    },
  });

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors },
  } = methods;
  const submitWithScroll = useFormScrollToError(handleSubmit, errors);

  const watchedValues = watch();
  const isDepositInvoice = watchedValues.kind === 'deposit';

  // Resolve the selected billing entity to a human name so the review step
  // shows "Acme Yacht Charters" instead of "company 4f2a1b…".
  const billingEntityRef = watchedValues.billingEntity ?? null;
  const { data: billingEntityName } = useQuery<{ name: string }>({
    queryKey: ['billing-entity-name', billingEntityRef?.type, billingEntityRef?.id],
    queryFn: async () => {
      if (!billingEntityRef) return { name: '' };
      const path =
        billingEntityRef.type === 'company'
          ? `/api/v1/companies/${billingEntityRef.id}`
          : `/api/v1/clients/${billingEntityRef.id}`;
      const res = await apiFetch<{
        data: { fullName?: string; name?: string };
      }>(path);
      return {
        name: res?.data?.fullName ?? res?.data?.name ?? '',
      };
    },
    enabled: !!billingEntityRef?.id,
    staleTime: 60_000,
  });

  // Pre-fill the billing entity from the linked interest's client on launch.
  useEffect(() => {
    if (prefilledInterest?.data && !watchedValues.billingEntity) {
      setValue(
        'billingEntity',
        { type: 'client', id: prefilledInterest.data.clientId },
        { shouldValidate: true },
      );
    }
    // We only want this to run when the interest data first arrives.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [prefilledInterest?.data?.clientId]);

  const lineItems = watchedValues.lineItems ?? [];
  const subtotal = lineItems.reduce(
    (sum, li) => sum + (Number(li.quantity) || 0) * (Number(li.unitPrice) || 0),
    0,
  );
  const isNet10 = watchedValues.paymentTerms === 'net10';
  const discountPct = isNet10 ? 2 : 0;
  const discountAmount = (subtotal * discountPct) / 100;
  const total = subtotal - discountAmount;

  const createMutation = useMutation({
    mutationFn: (data: CreateInvoiceInput) =>
      apiFetch<{ data?: { id?: string } }>('/api/v1/invoices', {
        method: 'POST',
        body: data,
      }),
    onSuccess: (res) => {
      const id = res?.data?.id;
      if (id) {
        router.push(`/${portSlug}/invoices/${id}`);
      } else {
        router.push(`/${portSlug}/invoices`);
      }
    },
  });

  async function goNext() {
    if (step === 1) {
      const valid = await methods.trigger([
        'billingEntity',
        'billingEmail',
        'billingAddress',
        'dueDate',
        'paymentTerms',
        'currency',
      ]);
      if (valid) setStep(2);
    } else if (step === 2) {
      setStep(3);
    }
  }

  function goBack() {
    setStep((s) => Math.max(1, s - 1));
  }

  function onSubmit(data: CreateInvoiceInput) {
    createMutation.mutate(data);
  }

  return (
    <div className="max-w-2xl mx-auto space-y-6">
      {/* Header - desktop only; mobile gets the title from the topbar */}
      <div className="hidden sm:flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={() => router.push(`/${portSlug}/invoices`)}>
          <ChevronLeft className="h-4 w-4" />
        </Button>
        <h1 className="text-xl font-semibold">New Invoice</h1>
      </div>

      {/* Step indicator */}
      <div className="flex items-center gap-2">
        {STEPS.map((s, idx) => (
          <div key={s.id} className="flex items-center gap-2">
            <div
              className={`flex items-center justify-center w-7 h-7 rounded-full text-xs font-medium ${
                step > s.id
                  ? 'bg-primary text-primary-foreground'
                  : step === s.id
                    ? 'bg-primary text-primary-foreground'
                    : 'bg-muted text-muted-foreground'
              }`}
            >
              {step > s.id ? <Check className="h-3.5 w-3.5" /> : s.id}
            </div>
            <span className={`text-sm ${step === s.id ? 'font-medium' : 'text-muted-foreground'}`}>
              {s.label}
            </span>
            {idx < STEPS.length - 1 && <div className="w-8 h-px bg-border mx-1" />}
          </div>
        ))}
      </div>

      <FormProvider {...methods}>
        <form onSubmit={submitWithScroll(onSubmit)} className="space-y-6">
          <FormErrorSummary
            errors={errors}
            labels={{
              billingEntity: 'Billing entity',
              billingEmail: 'Billing email',
              dueDate: 'Due date',
              lineItems: 'Line items',
              currency: 'Currency',
              paymentTerms: 'Payment terms',
            }}
          />
          {/* Step 1: Client Info */}
          {step === 1 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base">Client Information</CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                {isDepositInvoice ? (
                  <div className="flex items-start gap-3 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
                    <Wallet className="mt-0.5 h-4 w-4 shrink-0" />
                    <div className="min-w-0">
                      <p className="font-medium">Deposit invoice</p>
                      <p className="text-xs text-amber-800">
                        {prefilledInterest?.data
                          ? `Linked to ${prefilledInterest.data.clientName ?? 'interest'}${
                              prefilledInterest.data.berthMooringNumber
                                ? ` - Berth ${prefilledInterest.data.berthMooringNumber}`
                                : ''
                            }. Marking this invoice as paid will advance the interest to "Deposit 10%".`
                          : 'Marking this invoice as paid will advance the linked interest to "Deposit 10%".'}
                      </p>
                    </div>
                  </div>
                ) : null}
                <div className="space-y-2">
                  <Label>
                    Billing entity <span className="text-destructive">*</span>
                  </Label>
                  <OwnerPicker
                    value={watchedValues.billingEntity ?? null}
                    onChange={(ref) => {
                      if (ref) {
                        setValue('billingEntity', ref, { shouldValidate: true });
                      }
                    }}
                  />
                  {errors.billingEntity && (
                    <p className="text-xs text-destructive">
                      {errors.billingEntity.message ??
                        errors.billingEntity.id?.message ??
                        errors.billingEntity.type?.message}
                    </p>
                  )}
                  <p className="text-xs text-muted-foreground">
                    Select the client or company to invoice. Their name will be snapshotted into the
                    invoice.
                  </p>
                </div>

                <div className="space-y-1">
                  <Label htmlFor="billingEmail">Billing Email</Label>
                  <Input
                    id="billingEmail"
                    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 htmlFor="billingAddress">Billing Address</Label>
                  <Textarea
                    id="billingAddress"
                    {...register('billingAddress')}
                    placeholder="Address"
                    rows={3}
                  />
                </div>

                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-1">
                    <Label htmlFor="dueDate">
                      Due Date <span className="text-destructive">*</span>
                    </Label>
                    <Input id="dueDate" type="date" {...register('dueDate')} />
                    {errors.dueDate && (
                      <p className="text-xs text-destructive">{errors.dueDate.message}</p>
                    )}
                  </div>

                  <div className="space-y-1">
                    <Label>Payment Terms</Label>
                    <Select
                      defaultValue="net30"
                      onValueChange={(v) =>
                        setValue('paymentTerms', v as CreateInvoiceInput['paymentTerms'])
                      }
                    >
                      <SelectTrigger>
                        <SelectValue placeholder="Select terms" />
                      </SelectTrigger>
                      <SelectContent>
                        {PAYMENT_TERMS.map((t) => (
                          <SelectItem key={t.value} value={t.value}>
                            {t.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                <div className="space-y-1">
                  <Label>Currency</Label>
                  <CurrencySelect
                    value={watchedValues.currency ?? 'USD'}
                    onValueChange={(v) => setValue('currency', v, { shouldDirty: true })}
                    className="w-48"
                  />
                </div>

                <div className="space-y-1">
                  <Label htmlFor="notes">Notes</Label>
                  <Textarea
                    id="notes"
                    {...register('notes')}
                    placeholder="Payment instructions or notes..."
                    rows={3}
                  />
                </div>
              </CardContent>
            </Card>
          )}

          {/* Step 2: Line Items */}
          {step === 2 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base">Line Items</CardTitle>
              </CardHeader>
              <CardContent>
                <InvoiceLineItems name="lineItems" currency={watchedValues.currency ?? 'USD'} />
                {errors.lineItems && !Array.isArray(errors.lineItems) && (
                  <p className="text-xs text-destructive mt-2">
                    {(errors.lineItems as { message?: string }).message}
                  </p>
                )}
                {errors.root && (
                  <p className="text-xs text-destructive mt-2">{errors.root.message}</p>
                )}
              </CardContent>
            </Card>
          )}

          {/* Step 3: Review */}
          {step === 3 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base">Review & Create</CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="grid grid-cols-2 gap-4 text-sm">
                  <div>
                    <span className="text-muted-foreground">Billing Entity</span>
                    <p className="font-medium mt-0.5">
                      {watchedValues.billingEntity ? (
                        <>
                          {billingEntityName?.name ? (
                            <span>{billingEntityName.name}</span>
                          ) : (
                            <span className="text-muted-foreground">Loading…</span>
                          )}{' '}
                          <span className="text-xs text-muted-foreground capitalize">
                            ({watchedValues.billingEntity.type})
                          </span>
                        </>
                      ) : (
                        <span className="text-muted-foreground italic">Not selected</span>
                      )}
                    </p>
                  </div>
                  <div>
                    <span className="text-muted-foreground">Due Date</span>
                    <p className="font-medium mt-0.5">{watchedValues.dueDate}</p>
                  </div>
                  <div>
                    <span className="text-muted-foreground">Payment Terms</span>
                    <p className="font-medium mt-0.5 capitalize">{watchedValues.paymentTerms}</p>
                  </div>
                  <div>
                    <span className="text-muted-foreground">Currency</span>
                    <p className="font-medium mt-0.5">{watchedValues.currency}</p>
                  </div>
                </div>

                {lineItems.length > 0 && (
                  <div className="border rounded-md p-3 space-y-2">
                    <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
                      Line Items
                    </p>
                    {lineItems.map((li, i) => (
                      <div key={i} className="flex justify-between text-sm">
                        <span>{li.description}</span>
                        <span className="tabular-nums">
                          {formatCurrency(
                            Number(li.quantity) * Number(li.unitPrice),
                            watchedValues.currency,
                          )}
                        </span>
                      </div>
                    ))}
                  </div>
                )}

                <div className="border rounded-md p-3 space-y-1 text-sm">
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Subtotal</span>
                    <span className="tabular-nums">
                      {formatCurrency(subtotal, watchedValues.currency)}
                    </span>
                  </div>
                  {isNet10 && (
                    <div className="flex justify-between text-green-600">
                      <span>Net 10 Discount (~2%)</span>
                      <span className="tabular-nums">
                        -{formatCurrency(discountAmount, watchedValues.currency)}
                      </span>
                    </div>
                  )}
                  <div className="flex justify-between font-semibold border-t pt-2 mt-1">
                    <span>Total</span>
                    <span className="tabular-nums">
                      {formatCurrency(total, watchedValues.currency)}
                    </span>
                  </div>
                </div>

                {createMutation.isError && (
                  <p className="text-sm text-destructive">
                    Failed to create invoice. Please try again.
                  </p>
                )}
              </CardContent>
            </Card>
          )}

          {/* Navigation */}
          <div className="flex items-center justify-between">
            <Button type="button" variant="outline" onClick={goBack} disabled={step === 1}>
              <ChevronLeft className="mr-1.5 h-4 w-4" />
              Back
            </Button>

            {step < 3 ? (
              <Button type="button" onClick={goNext}>
                Next
                <ChevronRight className="ml-1.5 h-4 w-4" />
              </Button>
            ) : (
              <Button type="submit" disabled={createMutation.isPending}>
                {createMutation.isPending ? (
                  <Loader2 className="mr-1.5 h-4 w-4 animate-spin" />
                ) : (
                  <Check className="mr-1.5 h-4 w-4" />
                )}
                Create Invoice
              </Button>
            )}
          </div>
        </form>
      </FormProvider>
    </div>
  );
}
