import { Head, useForm } from '@inertiajs/react'
import { useState } from 'react'
import { toast } from 'sonner'
import { LimsAppLayout } from '@/layouts/lims-app-layout'
import { Button } from '@ui/components/ui/button'
import { Input } from '@ui/components/ui/input'
import { Label } from '@ui/components/ui/label'
import { Textarea } from '@ui/components/ui/textarea'
import { Card, CardContent, CardHeader, CardTitle } from '@ui/components/ui/card'
import { Checkbox } from '@ui/components/ui/checkbox'
import { Separator } from '@ui/components/ui/separator'
import { ComboboxDropdown } from '@ui/components/combobox-dropdown'
import SalesOrderController from '@/actions/App/Modules/SalesOrder/Infrastructure/Controllers/SalesOrderController'
import { Plus } from 'lucide-react'

interface OptionSimple {
    id: number
    code: string
    name: string
    item_id?: number | null
}

interface RegulationOption extends OptionSimple {
    short_name?: string | null
}

interface AppendixOption extends OptionSimple {
    regulation_id: number
    appendix_number?: string | null
}

interface ParamRow {
    parameter_id?: number | null
    method_id?: number | null
    parameter_name: string
    parameter_alias: string
    test_method: string
    unit: string
    specification: string
    unit_price: string
    cou: string
    is_additional: boolean
    notes: string
}

interface ItemRow {
    item_id: string
    regulation_id: string
    regulation_appendix_id: string
    sample_type_snapshot: string
    sample_points: string
    quantity: string
    unit: string
    unit_price: string
    discount_amount: string
    is_subcontract: boolean
    notes: string
    params: ParamRow[]
}

interface Props {
    sampleTypeOptions: OptionSimple[]
    regulationOptions: RegulationOption[]
    appendixOptions: AppendixOption[]
    stage: 'quotation' | 'sales_order'
}

function emptyParam(): ParamRow {
    return {
        parameter_id: null,
        method_id: null,
        parameter_name: '',
        parameter_alias: '',
        test_method: '',
        unit: '',
        specification: '',
        unit_price: '0',
        cou: '0',
        is_additional: false,
        notes: '',
    }
}

function emptyItem(): ItemRow {
    return {
        item_id: '',
        regulation_id: '',
        regulation_appendix_id: '',
        sample_type_snapshot: '',
        sample_points: '1',
        quantity: '1',
        unit: 'PAKET',
        unit_price: '0',
        discount_amount: '0',
        is_subcontract: false,
        notes: '',
        params: [emptyParam()],
    }
}

export default function SalesOrderCreate({
    sampleTypeOptions,
    regulationOptions,
    appendixOptions,
    stage,
}: Props) {
    const [loadingAutoByItem, setLoadingAutoByItem] = useState<number[]>([])

    const { data, setData, post, processing, errors } = useForm<{
        customer_id: string
        transaction_date: string
        sample_type_id: string
        branch_id: string
        tax_percentage: string
        deadline_date: string
        quotation_number: string
        priority: string
        is_repeat: boolean
        is_plan_sampling: boolean
        is_gmp_sampling: boolean
        is_recheck: boolean
        is_acceleration: boolean
        technical_note: string
        admin_note: string
        notes: string
        lhu_contact_name: string
        lhu_contact_phone: string
        lhu_delivery_address: string
        document_delivery_address: string
        items: ItemRow[]
    }>({
        customer_id: '',
        transaction_date: new Date().toISOString().substring(0, 10),
        sample_type_id: '',
        branch_id: '',
        tax_percentage: '12',
        deadline_date: '',
        quotation_number: '',
        priority: 'normal',
        is_repeat: false,
        is_plan_sampling: false,
        is_gmp_sampling: false,
        is_recheck: false,
        is_acceleration: false,
        technical_note: '',
        admin_note: '',
        notes: '',
        lhu_contact_name: '',
        lhu_contact_phone: '',
        lhu_delivery_address: '',
        document_delivery_address: '',
        items: [emptyItem()],
    })

    function setItem(index: number, field: keyof ItemRow, value: ItemRow[keyof ItemRow]) {
        const items = [...data.items]
        items[index] = { ...items[index], [field]: value }
        setData('items', items)
    }

    function setParam(itemIdx: number, paramIdx: number, field: keyof ParamRow, value: ParamRow[keyof ParamRow]) {
        const items = [...data.items]
        const params = [...items[itemIdx].params]
        params[paramIdx] = { ...params[paramIdx], [field]: value }
        items[itemIdx] = { ...items[itemIdx], params }
        setData('items', items)
    }

    function addItem() {
        setData('items', [...data.items, emptyItem()])
    }

    function removeItem(index: number) {
        setData('items', data.items.filter((_, i) => i !== index))
    }

    function addParam(itemIdx: number) {
        const items = [...data.items]
        items[itemIdx] = { ...items[itemIdx], params: [...items[itemIdx].params, emptyParam()] }
        setData('items', items)
    }

    const sampleTypeComboboxOptions = sampleTypeOptions.map((option) => ({
        value: String(option.id),
        label: `${option.code} - ${option.name}`,
    }))

    function removeParam(itemIdx: number, paramIdx: number) {
        const items = [...data.items]
        items[itemIdx] = { ...items[itemIdx], params: items[itemIdx].params.filter((_, i) => i !== paramIdx) }
        setData('items', items)
    }

    async function autoLoadFromQualityStandard(itemIdx: number) {
        if (loadingAutoByItem.includes(itemIdx)) {
            return
        }

        const item = data.items[itemIdx]
        if (!data.sample_type_id) {
            toast.error('Pilih Jenis Sampel pada header terlebih dahulu.')
            return
        }
        if (!item.regulation_id) {
            toast.error(`Pilih Regulasi untuk Item #${itemIdx + 1} terlebih dahulu.`)
            return
        }
        const regulationAppendices = appendixOptions.filter((appendix) => String(appendix.regulation_id) === item.regulation_id)
        if (regulationAppendices.length > 0 && !item.regulation_appendix_id) {
            toast.error(`Pilih Lampiran untuk Item #${itemIdx + 1} terlebih dahulu.`)
            return
        }

        try {
            setLoadingAutoByItem((prev) => [...prev, itemIdx])

            const params = new URLSearchParams({
                sample_type_id: data.sample_type_id,
                regulation_id: item.regulation_id,
            })
            if (item.regulation_appendix_id) {
                params.append('regulation_appendix_id', item.regulation_appendix_id)
            }

            const res = await fetch(`/sales-orders/quality-standard-params?${params.toString()}`, {
                headers: { Accept: 'application/json' },
            })
            if (!res.ok) {
                throw new Error('gagal memuat baku mutu')
            }

            const payload = await res.json() as {
                quality_standard: { code?: string | null, sample_type_name?: string | null } | null
                params: Array<{
                    parameter_id?: number | null
                    parameter_name?: string | null
                    method_id?: number | null
                    test_method?: string | null
                    unit?: string | null
                    specification?: string | null
                }>
            }

            if (!payload.quality_standard || payload.params.length === 0) {
                toast.warning('Baku mutu tidak ditemukan untuk kombinasi tersebut.')
                return
            }

            const mappedParams: ParamRow[] = payload.params.map((row) => ({
                parameter_id: row.parameter_id ?? null,
                method_id: row.method_id ?? null,
                parameter_name: row.parameter_name ?? '',
                parameter_alias: '',
                test_method: row.test_method ?? '',
                unit: row.unit ?? '',
                specification: row.specification ?? '',
                unit_price: '0',
                cou: '0',
                is_additional: false,
                notes: '',
            }))

            const items = [...data.items]
            items[itemIdx] = {
                ...items[itemIdx],
                sample_type_snapshot: payload.quality_standard.sample_type_name ?? items[itemIdx].sample_type_snapshot,
                params: mappedParams.length > 0 ? mappedParams : [emptyParam()],
            }
            setData('items', items)

            toast.success(`Parameter berhasil di-load dari ${payload.quality_standard.code ?? 'baku mutu'}.`)
        } catch {
            toast.error('Gagal mengambil parameter dari baku mutu.')
        } finally {
            setLoadingAutoByItem((prev) => prev.filter((idx) => idx !== itemIdx))
        }
    }

    function submit(e: React.FormEvent) {
        e.preventDefault()
        post(`${SalesOrderController.store().url}?stage=${stage}`)
    }

    const indexUrl = `${SalesOrderController.index().url}?stage=${stage}`
    const pageTitle = stage === 'quotation' ? 'Buat Quotation' : 'Buat Sales Order'
    const submitLabel = stage === 'quotation' ? 'Simpan Quotation' : 'Simpan Sales Order'

    return (
        <LimsAppLayout>
            <Head title={pageTitle} />
            <form onSubmit={submit} className='flex h-full flex-1 flex-col gap-6 p-4'>
                <div className='flex items-center justify-between'>
                    <div>
                        <h1 className='text-xl font-bold tracking-tight'>{pageTitle}</h1>
                        <p className='text-sm text-muted-foreground'>
                            {stage === 'quotation'
                                ? 'Isi detail quotation sebelum diproses jadi sales order'
                                : 'Isi detail permintaan pengujian'}
                        </p>
                    </div>
                    <div className='flex gap-2'>
                        <Button type='button' variant='outline' asChild>
                            <a href={indexUrl}>Batal</a>
                        </Button>
                        <Button type='submit' disabled={processing}>
                            {processing ? 'Menyimpan...' : submitLabel}
                        </Button>
                    </div>
                </div>

                <Card>
                    <CardHeader>
                        <CardTitle className='text-base'>Informasi Umum</CardTitle>
                    </CardHeader>
                    <CardContent className='grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3'>
                        <div className='space-y-1'>
                            <Label>ID Customer *</Label>
                            <Input type='number' value={data.customer_id} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('customer_id', e.target.value)} />
                            {errors.customer_id && <p className='text-xs text-destructive'>{errors.customer_id}</p>}
                        </div>
                        <div className='space-y-1'>
                            <Label>Tanggal Transaksi *</Label>
                            <Input type='date' value={data.transaction_date} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('transaction_date', e.target.value)} />
                        </div>
                        <div className='space-y-1'>
                            <Label>Jenis Sampel (Header)</Label>
                            <ComboboxDropdown
                                value={data.sample_type_id || undefined}
                                onValueChange={(value) => {
                                    setData('sample_type_id', value ?? '')

                                    const selected = sampleTypeOptions.find((option) => String(option.id) === value)
                                    if (!selected?.item_id) return

                                    const items = data.items.map((item) => ({
                                        ...item,
                                        item_id: item.item_id || String(selected.item_id),
                                        sample_type_snapshot: item.sample_type_snapshot || selected.name,
                                    }))
                                    setData('items', items)
                                }}
                                placeholder='Pilih jenis sampel...'
                                searchPlaceholder='Cari jenis sampel...'
                                emptyText='Jenis sampel tidak ditemukan.'
                                options={sampleTypeComboboxOptions}
                            />
                        </div>
                        <div className='space-y-1'>
                            <Label>Deadline</Label>
                            <Input type='date' value={data.deadline_date} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('deadline_date', e.target.value)} />
                        </div>
                        <div className='space-y-1'>
                            <Label>PPN (%)</Label>
                            <Input type='number' step='0.01' value={data.tax_percentage} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('tax_percentage', e.target.value)} />
                        </div>
                        <div className='space-y-1'>
                            <Label>Prioritas</Label>
                            <select
                                value={data.priority}
                                onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setData('priority', e.target.value)}
                                className='flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus:outline-none focus:ring-1 focus:ring-ring'
                            >
                                <option value='normal'>Normal</option>
                                <option value='urgent'>Urgent</option>
                                <option value='very_urgent'>Very Urgent</option>
                            </select>
                        </div>
                        <div className='col-span-full flex flex-wrap gap-6'>
                            {([
                                ['is_repeat', 'Repeat Order'],
                                ['is_plan_sampling', 'Plan Sampling'],
                                ['is_gmp_sampling', 'GMP Sampling'],
                                ['is_recheck', 'Recheck'],
                                ['is_acceleration', 'Percepatan'],
                            ] as const).map(([key, label]) => (
                                <div key={key} className='flex items-center gap-2'>
                                    <Checkbox id={key} checked={data[key]} onCheckedChange={(v: boolean | 'indeterminate') => setData(key, v === true)} />
                                    <Label htmlFor={key} className='cursor-pointer'>{label}</Label>
                                </div>
                            ))}
                        </div>
                    </CardContent>
                </Card>

                <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                        <CardTitle className='text-base'>Item Pengujian</CardTitle>
                        <Button type='button' size='sm' variant='outline' className='gap-1' onClick={addItem}>
                            <Plus className='h-3.5 w-3.5' /> Tambah Item
                        </Button>
                    </CardHeader>
                    <CardContent className='space-y-6'>
                        {data.items.map((item, itemIdx) => {
                            const filteredAppendices = item.regulation_id
                                ? appendixOptions.filter((a) => String(a.regulation_id) === item.regulation_id)
                                : []
                            const regulationOptionExists = item.regulation_id
                                ? regulationOptions.some((option) => String(option.id) === item.regulation_id)
                                : false
                            const safeRegulationId = regulationOptionExists ? item.regulation_id : ''
                            const appendixOptionExists = item.regulation_appendix_id
                                ? filteredAppendices.some((option) => String(option.id) === item.regulation_appendix_id)
                                : false
                            const safeAppendixId = appendixOptionExists ? item.regulation_appendix_id : ''

                            return (
                                <div key={itemIdx} className='space-y-4 rounded-lg border p-4'>
                                    <div className='flex items-center justify-between'>
                                        <span className='text-sm font-semibold text-muted-foreground'>Item #{itemIdx + 1}</span>
                                    </div>

                                    <div className='grid grid-cols-1 gap-3 md:grid-cols-4'>
                                        <div className='space-y-1'>
                                            <Label>Regulasi</Label>
                                            <ComboboxDropdown
                                                value={safeRegulationId || undefined}
                                                onValueChange={(value) => {
                                                    setItem(itemIdx, 'regulation_id', value ?? '')
                                                    setItem(itemIdx, 'regulation_appendix_id', '')
                                                }}
                                                placeholder='Pilih regulasi...'
                                                searchPlaceholder='Cari regulasi...'
                                                emptyText='Regulasi tidak ditemukan.'
                                                options={regulationOptions.map((option) => ({
                                                    value: String(option.id),
                                                    label: option.short_name ? `${option.short_name} - ${option.name}` : `${option.code} - ${option.name}`,
                                                }))}
                                            />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Lampiran</Label>
                                            <ComboboxDropdown
                                                value={safeAppendixId || undefined}
                                                onValueChange={(value) => setItem(itemIdx, 'regulation_appendix_id', value ?? '')}
                                                disabled={!safeRegulationId}
                                                placeholder='Tanpa lampiran'
                                                searchPlaceholder='Cari lampiran...'
                                                emptyText='Lampiran tidak ditemukan.'
                                                options={filteredAppendices.map((option) => ({
                                                    value: String(option.id),
                                                    label: option.appendix_number ? `${option.appendix_number} - ${option.name}` : `${option.code} - ${option.name}`,
                                                }))}
                                            />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Nama Sampel</Label>
                                            <Input value={item.sample_type_snapshot} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'sample_type_snapshot', e.target.value)} />
                                        </div>
                                        <div className='flex items-end'>
                                            <Button
                                                type='button'
                                                variant='default'
                                                className='w-full bg-teal-600 hover:bg-teal-700'
                                                disabled={loadingAutoByItem.includes(itemIdx) || !data.sample_type_id || !item.regulation_id}
                                                onClick={() => autoLoadFromQualityStandard(itemIdx)}
                                            >
                                                {loadingAutoByItem.includes(itemIdx) ? 'Memuat...' : 'Auto-load dari Baku Mutu'}
                                            </Button>
                                        </div>
                                    </div>

                                    <div className='grid grid-cols-2 gap-3 md:grid-cols-5'>
                                        <div className='space-y-1'>
                                            <Label>Jumlah Sampel</Label>
                                            <Input type='number' min={1} value={item.sample_points} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'sample_points', e.target.value)} />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Qty</Label>
                                            <Input type='number' min={1} value={item.quantity} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'quantity', e.target.value)} />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Unit</Label>
                                            <Input value={item.unit} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'unit', e.target.value)} />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Harga Satuan</Label>
                                            <Input type='number' min={0} value={item.unit_price} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'unit_price', e.target.value)} />
                                        </div>
                                        <div className='space-y-1'>
                                            <Label>Diskon Nominal</Label>
                                            <Input type='number' min={0} value={item.discount_amount} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setItem(itemIdx, 'discount_amount', e.target.value)} />
                                        </div>
                                    </div>

                                    <Separator />

                                    <div className='space-y-3'>
                                        <div className='flex items-center justify-between'>
                                            <span className='text-xs font-semibold uppercase tracking-wider text-muted-foreground'>Parameter</span>
                                            <Button type='button' size='sm' variant='ghost' className='h-7 gap-1 text-xs' onClick={() => addParam(itemIdx)}>
                                                <Plus className='h-3 w-3' /> Tambah
                                            </Button>
                                        </div>

                                        {item.params.map((param, paramIdx) => (
                                            <div key={paramIdx} className='grid grid-cols-2 gap-2 rounded-md bg-muted/30 p-3 md:grid-cols-4'>
                                                <div className='space-y-1'>
                                                    <Label className='text-xs'>Nama Parameter *</Label>
                                                    <Input className='h-8 text-sm' value={param.parameter_name} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setParam(itemIdx, paramIdx, 'parameter_name', e.target.value)} />
                                                </div>
                                                <div className='space-y-1'>
                                                    <Label className='text-xs'>Metode</Label>
                                                    <Input className='h-8 text-sm' value={param.test_method} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setParam(itemIdx, paramIdx, 'test_method', e.target.value)} />
                                                </div>
                                                <div className='space-y-1'>
                                                    <Label className='text-xs'>Satuan</Label>
                                                    <Input className='h-8 text-sm' value={param.unit} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setParam(itemIdx, paramIdx, 'unit', e.target.value)} />
                                                </div>
                                                <div className='space-y-1'>
                                                    <Label className='text-xs'>Spesifikasi</Label>
                                                    <div className='flex gap-1'>
                                                        <Input className='h-8 text-sm' value={param.specification} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setParam(itemIdx, paramIdx, 'specification', e.target.value)} />
                                                    </div>
                                                </div>
                                            </div>
                                        ))}
                                    </div>
                                </div>
                            )
                        })}
                    </CardContent>
                </Card>

                <Card>
                    <CardHeader>
                        <CardTitle className='text-base'>Catatan</CardTitle>
                    </CardHeader>
                    <CardContent className='grid grid-cols-1 gap-4 md:grid-cols-2'>
                        <div className='space-y-1'>
                            <Label>Catatan Teknis</Label>
                            <Textarea rows={3} value={data.technical_note} onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setData('technical_note', e.target.value)} />
                        </div>
                        <div className='space-y-1'>
                            <Label>Catatan Admin</Label>
                            <Textarea rows={3} value={data.admin_note} onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setData('admin_note', e.target.value)} />
                        </div>
                    </CardContent>
                </Card>

                <div className='sticky bottom-4 flex justify-end gap-2'>
                    <Button type='button' variant='outline' asChild>
                        <a href={indexUrl}>Batal</a>
                    </Button>
                    <Button type='submit' disabled={processing} className='shadow-lg'>
                        {processing ? 'Menyimpan...' : submitLabel}
                    </Button>
                </div>
            </form>
        </LimsAppLayout>
    )
}
