'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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle
} from '@/components/ui/sheet';
import { useAppForm, useFormFields } from '@/components/ui/tanstack-form';
import { opportunityProjectPartiesOptions } from '../api/queries';
import { createOpportunityMutation, updateOpportunityMutation } from '../api/mutations';
import type { OpportunityMutationPayload, OpportunityRecord, OpportunityReferenceData } from '../api/types';
import { opportunitySchema, type OpportunityFormValues } from '../schemas/opportunity.schema';

function toDefaultValues(
  opportunity: OpportunityRecord | undefined,
  referenceData: OpportunityReferenceData
): OpportunityFormValues {
  return {
    customerId: opportunity?.customerId ?? referenceData.customers[0]?.id ?? '',
    contactId: opportunity?.contactId ?? undefined,
    assignedToUserId: opportunity?.assignedToUserId ?? undefined,
    title: opportunity?.title ?? '',
    description: opportunity?.description ?? '',
    requirement: opportunity?.requirement ?? '',
    projectName: opportunity?.projectName ?? '',
    projectLocation: opportunity?.projectLocation ?? '',
    branchId: opportunity?.branchId ?? undefined,
    productType: opportunity?.productType ?? referenceData.productTypes[0]?.id ?? '',
    status: opportunity?.status ?? referenceData.statuses[0]?.id ?? '',
    priority:
      opportunity?.priority ?? referenceData.priorities[1]?.id ?? referenceData.priorities[0]?.id ?? '',
    leadChannel: opportunity?.leadChannel ?? undefined,
    estimatedValue: opportunity?.estimatedValue ?? undefined,
    chancePercent: opportunity?.chancePercent ?? undefined,
    expectedCloseDate: opportunity?.expectedCloseDate ? opportunity.expectedCloseDate.slice(0, 10) : '',
    competitor: opportunity?.competitor ?? '',
    source: opportunity?.source ?? '',
    isHotProject: opportunity?.isHotProject ?? false,
    notes: opportunity?.notes ?? '',
    isActive: opportunity?.isActive ?? true
  };
}

export function OpportunityFormSheet({
  opportunity,
  open,
  onOpenChange,
  referenceData,
  workspace = 'opportunity'
}: {
  opportunity?: OpportunityRecord;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  referenceData: OpportunityReferenceData;
  workspace?: 'lead' | 'opportunity';
}) {
  const isEdit = !!opportunity;
  const defaultValues = useMemo(
    () => toDefaultValues(opportunity, referenceData),
    [opportunity, referenceData]
  );
  const [selectedCustomerId, setSelectedCustomerId] = useState(defaultValues.customerId);
  const [projectParties, setProjectParties] = useState<ProjectPartyEditorItem[]>([]);
  const {
    FormTextField,
    FormTextareaField,
    FormSelectField,
    FormSwitchField,
    FormDatePickerField,
    FormCurrencyField,
    FormPercentageField
  } = useFormFields<OpportunityFormValues>();
  const projectPartiesQuery = useQuery({
    ...opportunityProjectPartiesOptions(opportunity?.id ?? ''),
    enabled: open && !!opportunity?.id
  });

  const createMutation = useMutation({
    ...createOpportunityMutation,
    onSuccess: () => {
      toast.success(`สร้าง${recordLabel}สำเร็จ`);
      onOpenChange(false);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : `ไม่สามารถสร้าง${recordLabel}ได้`)
  });

  const updateMutation = useMutation({
    ...updateOpportunityMutation,
    onSuccess: () => {
      toast.success(`อัปเดต${recordLabel}สำเร็จ`);
      onOpenChange(false);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : `ไม่สามารถอัปเดต${recordLabel}ได้`)
  });

  const contactsForCustomer = referenceData.contacts.filter(
    (contact) => contact.customerId === selectedCustomerId
  );
  const selectedCustomer = referenceData.customers.find((customer) => customer.id === selectedCustomerId);

  const form = useAppForm({
    defaultValues,
    validators: {
      onSubmit: opportunitySchema
    },
    onSubmit: async ({ value }) => {
      const payload: OpportunityMutationPayload = {
        customerId: value.customerId,
        contactId: value.contactId || null,
        assignedToUserId: value.assignedToUserId || null,
        title: value.title,
        description: value.description,
        requirement: value.requirement,
        projectName: value.projectName,
        projectLocation: value.projectLocation,
        branchId: value.branchId || null,
        productType: value.productType,
        status: value.status,
        priority: value.priority,
        leadChannel: value.leadChannel || null,
        estimatedValue:
          typeof value.estimatedValue === 'number' ? value.estimatedValue : null,
        chancePercent:
          typeof value.chancePercent === 'number' ? value.chancePercent : null,
        expectedCloseDate: value.expectedCloseDate || null,
        competitor: value.competitor,
        source: value.source,
        isHotProject: value.isHotProject ?? false,
        notes: value.notes,
        isActive: value.isActive ?? true,
        projectParties: projectParties
          .filter((item) => item.customerId && item.role)
          .map((item) => ({
            customerId: item.customerId,
            role: item.role,
            remark: item.remark || null
          }))
      };

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

      await createMutation.mutateAsync(payload);
    }
  });

  useEffect(() => {
    if (!open) {
      return;
    }

    setSelectedCustomerId(defaultValues.customerId);
    form.reset(defaultValues);
    setProjectParties(
      opportunity
        ? (projectPartiesQuery.data?.items ?? []).map((item) => ({
            key: item.id,
            customerId: item.customerId,
            role: item.role,
            remark: item.remark ?? ''
          }))
        : []
    );
  }, [defaultValues, opportunity, form, open, projectPartiesQuery.data?.items]);

  useEffect(() => {
    if (!open || isEdit) {
      return;
    }

    const ownerUserId =
      referenceData.customers.find((customer) => customer.id === selectedCustomerId)?.ownerUserId ?? '';

    form.setFieldValue('assignedToUserId', ownerUserId);
  }, [form, isEdit, open, referenceData.customers, selectedCustomerId]);

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

  const recordLabel = workspace === 'lead' ? 'ลีด' : 'โอกาสขาย';

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className='flex flex-col sm:max-w-4xl'>
        <SheetHeader>
          <SheetTitle>{isEdit ? `แก้ไข${recordLabel}` : `เพิ่ม${recordLabel}`}</SheetTitle>
          <SheetDescription>
            {workspace === 'lead'
              ? 'บันทึกข้อมูลลีดของฝ่ายการตลาดก่อนส่งต่อให้ฝ่ายขาย'
              : 'บันทึกข้อมูลโอกาสขายของฝ่ายขายก่อนเริ่มทำใบเสนอราคา'}
          </SheetDescription>
        </SheetHeader>

        <div className='flex-1 overflow-auto'>
          <form.AppForm>
            <form.Form id='opportunity-form-sheet' className='grid gap-4 md:grid-cols-2'>
              <form.AppField
                name='customerId'
                children={(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <field.FieldLabel>ลูกค้าผู้รับใบเสนอราคา *</field.FieldLabel>
                      <Select
                        value={field.state.value ?? ''}
                        onValueChange={(value) => {
                          field.handleChange(value);
                          field.handleBlur();
                          setSelectedCustomerId(value);
                          form.setFieldValue('contactId', '');
                        }}
                      >
                        <SelectTrigger aria-label='ลูกค้า'>
                          <SelectValue placeholder='เลือกลูกค้า' />
                        </SelectTrigger>
                        <SelectContent>
                          {referenceData.customers.map((customer) => (
                            <SelectItem key={customer.id} value={customer.id}>
                              {customer.name} ({customer.code})
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              />

              <form.AppField
                name='contactId'
                children={(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <field.FieldLabel>ผู้ติดต่อ</field.FieldLabel>
                      <Select
                        value={field.state.value ?? ''}
                        onValueChange={(value) => {
                          field.handleChange(value === '__none__' ? '' : value);
                          field.handleBlur();
                        }}
                      >
                        <SelectTrigger aria-label='ผู้ติดต่อ'>
                          <SelectValue placeholder='เลือกผู้ติดต่อ' />
                        </SelectTrigger>
                        <SelectContent>
                          {contactsForCustomer.length ? (
                            contactsForCustomer.map((contact) => (
                              <SelectItem key={contact.id} value={contact.id}>
                                {contact.name}
                                {contact.isPrimary ? ' (ผู้ติดต่อหลัก)' : ''}
                              </SelectItem>
                            ))
                          ) : (
                            <SelectItem value='__none__'>ไม่เลือกผู้ติดต่อ</SelectItem>
                          )}
                        </SelectContent>
                      </Select>
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              />
              <FormSelectField
                name='assignedToUserId'
                label='Suggested Sales Owner'
                description={
                  selectedCustomer?.ownerName
                    ? `Suggested from customer owner: ${selectedCustomer.ownerName}`
                    : 'Optional sales owner suggestion for this lead or opportunity'
                }
                options={referenceData.assignableUsers.map((user) => ({
                  value: user.id,
                  label: user.name
                }))}
              />

              <FormTextField
                name='title'
                label='ชื่อรายการ'
                required
                placeholder='Warehouse crane upgrade opportunity'
              />
              <FormTextField
                name='projectName'
                label='ชื่อโครงการ'
                placeholder='Bangna Warehouse Expansion'
              />
              <FormTextField
                name='projectLocation'
                label='สถานที่โครงการ'
                placeholder='Bangkok'
              />
              <FormTextField
                name='source'
                label='ที่มา'
                placeholder='Existing customer referral'
              />
              <FormSelectField
                name='branchId'
                label='สาขา'
                options={referenceData.branches.map((branch) => ({
                  value: branch.id,
                  label: branch.name
                }))}
              />
              <FormSelectField
                name='productType'
                label='ประเภทสินค้า'
                required
                options={referenceData.productTypes.map((item) => ({
                  value: item.id,
                  label: item.label
                }))}
              />
              <FormSelectField
                name='status'
                label='สถานะ'
                required
                options={referenceData.statuses.map((item) => ({
                  value: item.id,
                  label: item.label
                }))}
              />
              <FormSelectField
                name='priority'
                label='ความสำคัญ'
                required
                options={referenceData.priorities.map((item) => ({
                  value: item.id,
                  label: item.label
                }))}
              />
              <FormSelectField
                name='leadChannel'
                label='ที่มาของลีด'
                options={referenceData.leadChannels.map((item) => ({
                  value: item.id,
                  label: item.label
                }))}
              />
              <FormCurrencyField
                name='estimatedValue'
                label='มูลค่าประมาณการ'
                currencyLabel='THB'
                placeholder='2500000'
              />
              <FormPercentageField
                name='chancePercent'
                label='โอกาสปิดการขาย %'
                placeholder='60'
              />
              <FormDatePickerField
                name='expectedCloseDate'
                label='วันที่คาดว่าจะปิดการขาย'
              />
              <FormTextField name='competitor' label='คู่แข่ง' placeholder='Other vendor name' />
              <div className='md:col-span-2'>
                <FormTextareaField
                  name='description'
                  size='md'
                  label='รายละเอียด'
                  placeholder='สรุปภาพรวมของลีดหรือโอกาสขาย'
                />
              </div>
              <div className='md:col-span-2'>
                <FormTextareaField
                  name='requirement'
                  size='md'
                  label='ความต้องการ'
                  placeholder='ความต้องการเชิงเทคนิคหรือเชิงพาณิชย์'
                />
              </div>
              <div className='md:col-span-2'>
                <FormTextareaField
                  name='notes'
                  size='md'
                  label='หมายเหตุ'
                  placeholder='หมายเหตุภายใน อุปสรรค หรือข้อมูลประกอบการส่งต่องาน'
                />
              </div>
              <div className='md:col-span-2 grid gap-4 md:grid-cols-2'>
                <FormSwitchField
                  name='isHotProject'
                  label='โครงการด่วน'
                  description='ใช้สำหรับงานเร่งด่วนหรือโครงการสำคัญเชิงกลยุทธ์'
                />
                <FormSwitchField
                  name='isActive'
                  label='ใช้งานอยู่'
                  description='รายการที่ปิดใช้งานจะยังอยู่ในประวัติ แต่ไม่ควรถูกดำเนินการต่อ'
                />
              </div>
              <div className='md:col-span-2'>
                <ProjectPartiesEditor
                  customers={referenceData.customers}
                  roles={referenceData.projectPartyRoles}
                  items={projectParties}
                  onChange={setProjectParties}
                />
              </div>
            </form.Form>
          </form.AppForm>
        </div>

        <SheetFooter>
          <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
            ยกเลิก
          </Button>
          <Button type='submit' form='opportunity-form-sheet' isLoading={isPending}>
            <Icons.check className='mr-2 h-4 w-4' />
            {isEdit ? `อัปเดต${recordLabel}` : `สร้าง${recordLabel}`}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

export function OpportunityFormSheetTrigger({
  referenceData,
  workspace = 'opportunity'
}: {
  referenceData: OpportunityReferenceData;
  workspace?: 'lead' | 'opportunity';
}) {
  const [open, setOpen] = React.useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        <Icons.add className='mr-2 h-4 w-4' /> {workspace === 'lead' ? 'เพิ่มลีด' : 'เพิ่มโอกาสขาย'}
      </Button>
      <OpportunityFormSheet
        open={open}
        onOpenChange={setOpen}
        referenceData={referenceData}
        workspace={workspace}
      />
    </>
  );
}

