import { useForm } from '@inertiajs/react'
import { useEffect, useState } from 'react'
import { toast } from 'sonner'
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 { Checkbox } from '@ui/components/ui/checkbox'
import { ComboboxDropdown, type ComboboxOption } from '@ui/components/combobox-dropdown'
import { type Method } from '@/types/glims'
import MethodController from '@/actions/App/Modules/MasterData/Infrastructure/Controllers/MethodController'

interface MethodFormProps {
    method?: Method
    unitOptions: { id: number; name: string }[]
    onSuccess: () => void
    onCancel: () => void
}

async function fetchOptions(endpoint: string, search = ''): Promise<ComboboxOption[]> {
    const url = `/master-data/${endpoint}` + (search ? `?search=${encodeURIComponent(search)}` : '')
    const res = await fetch(url, { headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' } })
    if (!res.ok) return []
    const data = await res.json()
    return Array.isArray(data) ? data : (data.data ?? [])
}

export function MethodForm({ method, unitOptions, onSuccess, onCancel }: MethodFormProps) {
    const { data, setData, post, put, transform, processing, errors } = useForm({
        code:                     method?.code ?? '',
        name:                     method?.name ?? '',
        description:              method?.description ?? '',
        procedure_summary:        method?.procedure_summary ?? '',
        detection_limit:          method?.detection_limit ?? '',
        measurement_unit:         method?.measurement_unit ?? '',
        equipment_required:       method?.equipment_required ?? ([] as string[]),
        reagent_required:         method?.reagent_required ?? ([] as string[]),
        estimated_duration_hours: method?.estimated_duration_hours ?? '',
        is_active:                method?.is_active ?? true,
    })

    const [equipmentOptions, setEquipmentOptions] = useState<ComboboxOption[]>([])
    const [reagentOptions,   setReagentOptions]   = useState<ComboboxOption[]>([])
    const [loadingEquip, setLoadingEquip] = useState(false)
    const [loadingReag, setLoadingReag] = useState(false)

    // Load options on mount so selected values are visible immediately
    useEffect(() => {
        setLoadingEquip(true)
        fetchOptions('gwin-items/equipment/options')
            .then((rows) => {
                const existing = (method?.equipment_required ?? []).map((v) => ({ value: v, label: v }))
                const merged = [...rows]
                for (const item of existing) {
                    if (!merged.some((o) => o.value === item.value)) {
                        merged.push(item)
                    }
                }
                setEquipmentOptions(merged)
            })
            .finally(() => setLoadingEquip(false))

        setLoadingReag(true)
        fetchOptions('gwin-items/reagent/options')
            .then((rows) => {
                const existing = (method?.reagent_required ?? []).map((v) => ({ value: v, label: v }))
                const merged = [...rows]
                for (const item of existing) {
                    if (!merged.some((o) => o.value === item.value)) {
                        merged.push(item)
                    }
                }
                setReagentOptions(merged)
            })
            .finally(() => setLoadingReag(false))
    }, [method?.equipment_required, method?.reagent_required])

    function submit(e: React.FormEvent) {
        e.preventDefault()

        transform((formData) => ({
            ...formData,
            detection_limit:          formData.detection_limit ? Number(formData.detection_limit) : null,
            estimated_duration_hours: formData.estimated_duration_hours ? Number(formData.estimated_duration_hours) : null,
        }))

        if (method) {
            put(MethodController.update(method).url, {
                onSuccess: () => { toast.success('Metode berhasil diperbarui.'); onSuccess() },
                onError:   (errs) => toast.error(Object.values(errs)[0] ?? 'Terjadi kesalahan.'),
            })
        } else {
            post(MethodController.store().url, {
                onSuccess: () => { toast.success('Metode berhasil ditambahkan.'); onSuccess() },
                onError:   (errs) => toast.error(Object.values(errs)[0] ?? 'Terjadi kesalahan.'),
            })
        }
    }

    return (
        <form onSubmit={submit} className='space-y-4'>
            <div className='grid grid-cols-1 gap-4 sm:grid-cols-2'>
                <div className='space-y-1.5'>
                    <Label htmlFor='m-code'>
                        Kode
                    </Label>
                    <p className='text-xs text-muted-foreground'>Opsional. Jika dikosongkan, sistem akan generate kode otomatis.</p>
                    <Input
                        id='m-code'
                        value={data.code}
                        onChange={e => setData('code', e.target.value.toUpperCase())}
                        placeholder='e.g. SNI_BOD'
                        disabled={!!method}
                    />
                    {errors.code && <p className='text-xs text-destructive'>{errors.code}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='m-name'>
                        Nama Metode <span className='text-destructive'>*</span>
                    </Label>
                    <Input
                        id='m-name'
                        value={data.name}
                        onChange={e => setData('name', e.target.value)}
                        placeholder='e.g. SNI 6989.72:2009'
                    />
                    {errors.name && <p className='text-xs text-destructive'>{errors.name}</p>}
                </div>

                <div className='col-span-full space-y-1.5'>
                    <Label htmlFor='m-desc'>Deskripsi</Label>
                    <Textarea
                        id='m-desc'
                        rows={3}
                        value={data.description}
                        onChange={e => setData('description', e.target.value)}
                        placeholder='Deskripsi metode pengujian...'
                    />
                    {errors.description && <p className='text-xs text-destructive'>{errors.description}</p>}
                </div>

                <div className='col-span-full space-y-1.5'>
                    <Label htmlFor='m-procedure'>Ringkasan Prosedur</Label>
                    <Textarea
                        id='m-procedure'
                        rows={3}
                        value={data.procedure_summary}
                        onChange={e => setData('procedure_summary', e.target.value)}
                        placeholder='Langkah utama prosedur pengujian...'
                    />
                    {errors.procedure_summary && <p className='text-xs text-destructive'>{errors.procedure_summary}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='m-dl'>Batas Deteksi</Label>
                    <Input
                        id='m-dl'
                        type='number'
                        min='0'
                        step='0.000001'
                        value={data.detection_limit}
                        onChange={e => setData('detection_limit', e.target.value)}
                        placeholder='e.g. 0.001'
                    />
                    {errors.detection_limit && <p className='text-xs text-destructive'>{errors.detection_limit}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='m-unit'>Satuan Ukur</Label>
                    <ComboboxDropdown
                        value={data.measurement_unit || undefined}
                        onValueChange={(value) => setData('measurement_unit', value ?? '')}
                        placeholder='Pilih satuan...'
                        options={unitOptions.map((u) => ({ value: u.name, label: u.name }))}
                        searchPlaceholder='Cari satuan...'
                        emptyText='Satuan tidak ditemukan.'
                    />
                    {errors.measurement_unit && <p className='text-xs text-destructive'>{errors.measurement_unit}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='m-duration'>Estimasi Durasi (jam)</Label>
                    <Input
                        id='m-duration'
                        type='number'
                        min='0'
                        step='0.01'
                        value={data.estimated_duration_hours}
                        onChange={e => setData('estimated_duration_hours', e.target.value)}
                        placeholder='e.g. 2.5'
                    />
                    {errors.estimated_duration_hours && <p className='text-xs text-destructive'>{errors.estimated_duration_hours}</p>}
                </div>

                {/* ─── Alat Diperlukan — from GWIN equipment ─── */}
                <div className='col-span-full space-y-1.5'>
                    <Label>
                        Alat Diperlukan
                        <span className='text-muted-foreground ml-1 text-xs font-normal'>(dari master alat GLIMS)</span>
                    </Label>
                    <ComboboxDropdown
                        multiple
                        options={equipmentOptions}
                        value={data.equipment_required}
                        onValueChange={vals => setData('equipment_required', vals)}
                        placeholder='Pilih peralatan...'
                        searchPlaceholder='Cari peralatan...'
                        emptyText='Tidak ada peralatan ditemukan'
                        searchable
                        clearable
                        isPending={loadingEquip}
                        className='w-full'
                    />
                    {errors.equipment_required && (
                        <p className='text-xs text-destructive'>{errors.equipment_required as unknown as string}</p>
                    )}
                </div>

                {/* ─── Reagen Diperlukan — from GWIN reagents ─── */}
                <div className='col-span-full space-y-1.5'>
                    <Label>
                        Reagen Diperlukan
                        <span className='text-muted-foreground ml-1 text-xs font-normal'>(dari master reagen GLIMS)</span>
                    </Label>
                    <ComboboxDropdown
                        multiple
                        options={reagentOptions}
                        value={data.reagent_required}
                        onValueChange={vals => setData('reagent_required', vals)}
                        placeholder='Pilih reagen...'
                        searchPlaceholder='Cari reagen...'
                        emptyText='Tidak ada reagen ditemukan'
                        searchable
                        clearable
                        isPending={loadingReag}
                        className='w-full'
                    />
                    {errors.reagent_required && (
                        <p className='text-xs text-destructive'>{errors.reagent_required as unknown as string}</p>
                    )}
                </div>

                <div className='col-span-full flex items-center gap-2'>
                    <Checkbox
                        id='m-active'
                        checked={data.is_active}
                        onCheckedChange={v => setData('is_active', !!v)}
                    />
                    <Label htmlFor='m-active' className='cursor-pointer font-normal'>
                        Metode aktif
                    </Label>
                </div>
            </div>

            <div className='flex justify-end gap-2 pt-2'>
                <Button type='button' variant='outline' onClick={onCancel} disabled={processing}>
                    Batal
                </Button>
                <Button type='submit' disabled={processing}>
                    {processing ? 'Menyimpan...' : method ? 'Simpan Perubahan' : 'Simpan'}
                </Button>
            </div>
        </form>
    )
}
