'use client';

import * as React from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Icons } from '@/components/icons';
import { Button } from '@/components/ui/button';
import {
  ProjectPartiesEditor,
  type ProjectPartyEditorItem
} from '@/features/crm/components/project-parties-editor';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle
} from '@/components/ui/sheet';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { quotationCustomersOptions } from '../api/queries';
import { createQuotationMutation, updateQuotationMutation } from '../api/mutations';
import type { QuotationMutationPayload, QuotationRecord, QuotationReferenceData } from '../api/types';

type FormState = {
  enquiryId: string;
  customerId: string;
  contactId: string;
  quotationDate: string;
  validUntil: string;
  quotationType: string;
  projectName: string;
  projectLocation: string;
  attention: string;
  branchId: string;
  currency: string;
  exchangeRate: string;
  status: string;
  chancePercent: string;
  competitor: string;
  reference: string;
  notes: string;
  salesmanId: string;
  discount: string;
  discountType: string;
  taxRate: string;
  sentVia: string;
  revisionRemark: string;
  isHotProject: boolean;
  isActive: boolean;
};

function toFormState(
  quotation: QuotationRecord | undefined,
  referenceData: QuotationReferenceData
): FormState {
  return {
    enquiryId: quotation?.enquiryId ?? '',
    customerId: quotation?.customerId ?? referenceData.customers[0]?.id ?? '',
    contactId: quotation?.contactId ?? '',
    quotationDate:
      quotation?.quotationDate?.slice(0, 10) ?? new Date().toISOString().slice(0, 10),
    validUntil: quotation?.validUntil?.slice(0, 10) ?? '',
    quotationType: quotation?.quotationType ?? referenceData.quotationTypes[0]?.id ?? '',
    projectName: quotation?.projectName ?? '',
    projectLocation: quotation?.projectLocation ?? '',
    attention: quotation?.attention ?? '',
    branchId: quotation?.branchId ?? '',
    currency: quotation?.currency ?? referenceData.currencies[0]?.id ?? '',
    exchangeRate: String(quotation?.exchangeRate ?? 1),
    status: quotation?.status ?? referenceData.statuses[0]?.id ?? '',
    chancePercent:
      quotation?.chancePercent === null || quotation?.chancePercent === undefined
        ? ''
        : String(quotation.chancePercent),
    competitor: quotation?.competitor ?? '',
    reference: quotation?.reference ?? '',
    notes: quotation?.notes ?? '',
    salesmanId: quotation?.salesmanId ?? '',
    discount: String(quotation?.discount ?? 0),
    discountType: quotation?.discountType ?? '',
    taxRate: String(quotation?.taxRate ?? 0),
    sentVia: quotation?.sentVia ?? '',
    revisionRemark: quotation?.revisionRemark ?? '',
    isHotProject: quotation?.isHotProject ?? false,
    isActive: quotation?.isActive ?? true
  };
}

function Field({
  label,
  children,
  className
}: {
  label: string;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={className}>
      <div className='mb-2 text-sm font-medium'>{label}</div>
      {children}
    </div>
  );
}

export function QuotationFormSheet({
  quotation,
  open,
  onOpenChange,
  referenceData
}: {
  quotation?: QuotationRecord;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  referenceData: QuotationReferenceData;
}) {
  const isEdit = !!quotation;
  const defaultState = useMemo(() => toFormState(quotation, referenceData), [quotation, referenceData]);
  const [state, setState] = useState<FormState>(defaultState);
  const [projectParties, setProjectParties] = useState<ProjectPartyEditorItem[]>([]);
  const projectPartiesQuery = useQuery({
    ...quotationCustomersOptions(quotation?.id ?? ''),
    enabled: open && !!quotation?.id
  });

  const createMutation = useMutation({
    ...createQuotationMutation,
    onSuccess: () => {
      toast.success('Quotation created successfully');
      onOpenChange(false);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to create quotation')
  });

  const updateMutation = useMutation({
    ...updateQuotationMutation,
    onSuccess: () => {
      toast.success('Quotation updated successfully');
      onOpenChange(false);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update quotation')
  });

  useEffect(() => {
    if (open) {
      setState(defaultState);
      setProjectParties(
        quotation
          ? (projectPartiesQuery.data?.items ?? []).map((item) => ({
              key: item.id,
              customerId: item.customerId,
              role: item.role,
              remark: item.remark ?? ''
            }))
          : []
      );
    }
  }, [defaultState, open, projectPartiesQuery.data?.items, quotation]);

  const contacts = useMemo(
    () => referenceData.contacts.filter((item) => item.customerId === state.customerId),
    [referenceData.contacts, state.customerId]
  );

  function setField<K extends keyof FormState>(key: K, value: FormState[K]) {
    setState((current) => ({ ...current, [key]: value }));
  }

  function handleEnquiryChange(value: string) {
    const enquiry = referenceData.enquiries.find((item) => item.id === value);
    setState((current) => ({
      ...current,
      enquiryId: value === '__none__' ? '' : value,
      customerId: enquiry?.customerId ?? current.customerId,
      contactId: enquiry?.contactId ?? '',
      projectName: enquiry?.projectName ?? current.projectName,
      projectLocation: enquiry?.projectLocation ?? current.projectLocation,
      branchId: enquiry?.branchId ?? current.branchId
    }));
  }

  async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    const payload: QuotationMutationPayload = {
      enquiryId: state.enquiryId || null,
      customerId: state.customerId,
      contactId: state.contactId || null,
      quotationDate: state.quotationDate,
      validUntil: state.validUntil || null,
      quotationType: state.quotationType,
      projectName: state.projectName,
      projectLocation: state.projectLocation,
      attention: state.attention,
      branchId: state.branchId || null,
      currency: state.currency,
      exchangeRate: state.exchangeRate ? Number(state.exchangeRate) : 1,
      status: state.status,
      chancePercent: state.chancePercent ? Number(state.chancePercent) : null,
      isHotProject: state.isHotProject,
      competitor: state.competitor,
      reference: state.reference,
      notes: state.notes,
      salesmanId: state.salesmanId || null,
      discount: state.discount ? Number(state.discount) : 0,
      discountType: state.discountType || null,
      taxRate: state.taxRate ? Number(state.taxRate) : 0,
      sentVia: state.sentVia || null,
      revisionRemark: state.revisionRemark || null,
      isActive: state.isActive,
      projectParties: projectParties
        .filter((item) => item.customerId && item.role)
        .map((item) => ({
          customerId: item.customerId,
          role: item.role,
          remark: item.remark || null
        }))
    };

    if (isEdit && quotation) {
      await updateMutation.mutateAsync({ id: quotation.id, values: payload });
      return;
    }

    await createMutation.mutateAsync(payload);
  }

  const isPending = createMutation.isPending || updateMutation.isPending;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className='flex flex-col sm:max-w-5xl'>
        <SheetHeader>
          <SheetTitle>{isEdit ? 'Edit Quotation' : 'New Quotation'}</SheetTitle>
          <SheetDescription>
            Capture quotation header data, billing customer, project parties, and commercial context.
          </SheetDescription>
        </SheetHeader>

        <form id='quotation-form-sheet' onSubmit={onSubmit} className='flex-1 overflow-auto'>
          <div className='grid gap-4 py-4 md:grid-cols-2'>
            <Field label='Enquiry'>
              <Select value={state.enquiryId || '__none__'} onValueChange={handleEnquiryChange}>
                <SelectTrigger>
                  <SelectValue placeholder='Select enquiry' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>No linked enquiry</SelectItem>
                  {referenceData.enquiries.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.code} - {item.title}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='ลูกค้าผู้รับใบเสนอราคา'>
              <Select
                value={state.customerId}
                onValueChange={(value) => {
                  setField('customerId', value);
                  setField('contactId', '');
                }}
              >
                <SelectTrigger>
                  <SelectValue placeholder='Select customer' />
                </SelectTrigger>
                <SelectContent>
                  {referenceData.customers.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.name} ({item.code})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Contact'>
              <Select
                value={state.contactId || '__none__'}
                onValueChange={(value) => setField('contactId', value === '__none__' ? '' : value)}
              >
                <SelectTrigger>
                  <SelectValue placeholder='Select contact' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>No contact</SelectItem>
                  {contacts.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Quotation Type'>
              <Select value={state.quotationType} onValueChange={(value) => setField('quotationType', value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select type' />
                </SelectTrigger>
                <SelectContent>
                  {referenceData.quotationTypes.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Quotation Date'>
              <Input type='date' value={state.quotationDate} onChange={(e) => setField('quotationDate', e.target.value)} />
            </Field>

            <Field label='Valid Until'>
              <Input type='date' value={state.validUntil} onChange={(e) => setField('validUntil', e.target.value)} />
            </Field>

            <Field label='Branch'>
              <Select value={state.branchId || '__none__'} onValueChange={(value) => setField('branchId', value === '__none__' ? '' : value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select branch' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>Unassigned</SelectItem>
                  {referenceData.branches.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Status'>
              <Select value={state.status} onValueChange={(value) => setField('status', value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select status' />
                </SelectTrigger>
                <SelectContent>
                  {referenceData.statuses.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Currency'>
              <Select value={state.currency} onValueChange={(value) => setField('currency', value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select currency' />
                </SelectTrigger>
                <SelectContent>
                  {referenceData.currencies.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Exchange Rate'>
              <Input value={state.exchangeRate} onChange={(e) => setField('exchangeRate', e.target.value)} type='number' step='0.0001' />
            </Field>

            <Field label='Project Name'>
              <Input value={state.projectName} onChange={(e) => setField('projectName', e.target.value)} placeholder='Project name' />
            </Field>

            <Field label='Project Location'>
              <Input value={state.projectLocation} onChange={(e) => setField('projectLocation', e.target.value)} placeholder='Project location' />
            </Field>

            <Field label='Attention'>
              <Input value={state.attention} onChange={(e) => setField('attention', e.target.value)} placeholder='Attention line' />
            </Field>

            <Field label='Reference'>
              <Input value={state.reference} onChange={(e) => setField('reference', e.target.value)} placeholder='Reference note' />
            </Field>

            <Field label='Salesman'>
              <Select value={state.salesmanId || '__none__'} onValueChange={(value) => setField('salesmanId', value === '__none__' ? '' : value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select salesman' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>Unassigned</SelectItem>
                  {referenceData.salesmen.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Chance %'>
              <Input value={state.chancePercent} onChange={(e) => setField('chancePercent', e.target.value)} type='number' min='0' max='100' />
            </Field>

            <Field label='Discount'>
              <Input value={state.discount} onChange={(e) => setField('discount', e.target.value)} type='number' step='0.01' />
            </Field>

            <Field label='Discount Type'>
              <Select value={state.discountType || '__none__'} onValueChange={(value) => setField('discountType', value === '__none__' ? '' : value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select discount type' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>None</SelectItem>
                  {referenceData.discountTypes.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Tax Rate %'>
              <Input value={state.taxRate} onChange={(e) => setField('taxRate', e.target.value)} type='number' step='0.01' />
            </Field>

            <Field label='Sent Via'>
              <Select value={state.sentVia || '__none__'} onValueChange={(value) => setField('sentVia', value === '__none__' ? '' : value)}>
                <SelectTrigger>
                  <SelectValue placeholder='Select sent via' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>Not sent yet</SelectItem>
                  {referenceData.sentVias.map((item) => (
                    <SelectItem key={item.id} value={item.id}>
                      {item.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>

            <Field label='Competitor'>
              <Input value={state.competitor} onChange={(e) => setField('competitor', e.target.value)} placeholder='Competitor' />
            </Field>

            <div className='md:col-span-2'>
              <ProjectPartiesEditor
                customers={referenceData.customers}
                roles={referenceData.projectPartyRoles}
                items={projectParties}
                onChange={setProjectParties}
              />
            </div>

            <div className='md:col-span-2'>
              <Field label='Notes'>
                <Textarea value={state.notes} onChange={(e) => setField('notes', e.target.value)} placeholder='Internal notes' />
              </Field>
            </div>

            <div className='md:col-span-2'>
              <Field label='Revision Remark'>
                <Textarea value={state.revisionRemark} onChange={(e) => setField('revisionRemark', e.target.value)} placeholder='Revision note or approval context' />
              </Field>
            </div>

            <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
              <div>
                <div className='font-medium'>Hot Project</div>
                <div className='text-muted-foreground text-sm'>Highlight urgent or strategic deals.</div>
              </div>
              <Switch checked={state.isHotProject} onCheckedChange={(checked) => setField('isHotProject', checked)} />
            </div>

            <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
              <div>
                <div className='font-medium'>Active Record</div>
                <div className='text-muted-foreground text-sm'>Inactive quotations stay as history only.</div>
              </div>
              <Switch checked={state.isActive} onCheckedChange={(checked) => setField('isActive', checked)} />
            </div>
          </div>
        </form>

        <SheetFooter>
          <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button type='submit' form='quotation-form-sheet' isLoading={isPending}>
            <Icons.check className='mr-2 h-4 w-4' />
            {isEdit ? 'Update Quotation' : 'Create Quotation'}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

export function QuotationFormSheetTrigger({
  referenceData
}: {
  referenceData: QuotationReferenceData;
}) {
  const [open, setOpen] = React.useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        <Icons.add className='mr-2 h-4 w-4' /> Add Quotation
      </Button>
      <QuotationFormSheet open={open} onOpenChange={setOpen} referenceData={referenceData} />
    </>
  );
}
