import { useEffect, useState } from 'react'
import { useForm } from '@inertiajs/react'
import { toast } from 'sonner'
import { Button } from '@ui/components/ui/button'
import { Checkbox } from '@ui/components/ui/checkbox'
import { Input } from '@ui/components/ui/input'
import { Label } from '@ui/components/ui/label'
import { Textarea } from '@ui/components/ui/textarea'
import { type TestTemplate } from '@/types/glims'

interface OptionSimple {
    id: number
    code: string
    name: string
}

interface TestTemplateParamFormProps {
    testTemplate: TestTemplate
    parameterOptions: OptionSimple[]
    methodOptions: OptionSimple[]
    param?: NonNullable<TestTemplate['params']>[number]
    onSuccess: () => void
    onCancel: () => void
}

export function TestTemplateParamForm({
    testTemplate,
    parameterOptions,
    methodOptions,
    param,
    onSuccess,
    onCancel,
}: TestTemplateParamFormProps) {
    const [availableMethods, setAvailableMethods] = useState<OptionSimple[]>(methodOptions)
    const [isLoadingMethods, setIsLoadingMethods] = useState(false)

    const { data, setData, post, put, transform, processing, errors } = useForm({
        parameter_id: String(param?.parameter_id ?? ''),
        method_id: param?.method_id ? String(param.method_id) : '',
        unit: param?.unit ?? '',
        is_required: param?.is_required ?? false,
        sort_order: String(param?.sort_order ?? 0),
        description: param?.description ?? '',
    })

    useEffect(() => {
        const parameterId = data.parameter_id
        if (!parameterId) {
            setAvailableMethods(methodOptions)
            return
        }

        const controller = new AbortController()
        setIsLoadingMethods(true)

        fetch(`/master-data/methods/options?parameter_id=${encodeURIComponent(parameterId)}`, {
            signal: controller.signal,
            headers: { Accept: 'application/json' },
        })
            .then(async (res) => {
                if (!res.ok) throw new Error('Gagal memuat metode')
                return res.json() as Promise<OptionSimple[]>
            })
            .then((rows) => {
                setAvailableMethods(rows)
                if (data.method_id && !rows.some((item) => String(item.id) === data.method_id)) {
                    setData('method_id', '')
                }
            })
            .catch((error: unknown) => {
                if (error instanceof DOMException && error.name === 'AbortError') return
                setAvailableMethods([])
            })
            .finally(() => setIsLoadingMethods(false))

        return () => controller.abort()
    }, [data.parameter_id, methodOptions, setData, data.method_id])

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

        transform((formData) => ({
            ...formData,
            parameter_id: Number(formData.parameter_id),
            method_id: formData.method_id ? Number(formData.method_id) : null,
            unit: formData.unit || null,
            is_required: !!formData.is_required,
            sort_order: formData.sort_order ? Number(formData.sort_order) : 0,
            description: formData.description || null,
        }))

        const base = `/master-data/test-templates/${testTemplate.id}/parameters`

        if (param) {
            put(`${base}/${param.id}`, {
                onSuccess: () => {
                    toast.success('Parameter template uji berhasil diperbarui.')
                    onSuccess()
                },
                onError: (errorBag) => toast.error(Object.values(errorBag)[0] ?? 'Terjadi kesalahan.'),
            })
            return
        }

        post(base, {
            onSuccess: () => {
                toast.success('Parameter template uji berhasil ditambahkan.')
                onSuccess()
            },
            onError: (errorBag) => toast.error(Object.values(errorBag)[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='ttp-parameter'>
                        Parameter <span className='text-destructive'>*</span>
                    </Label>
                    <select
                        id='ttp-parameter'
                        value={data.parameter_id}
                        onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
                            const value = e.target.value
                            setData('parameter_id', value)
                            setData('method_id', '')
                        }}
                        className='w-full rounded-md border bg-background px-3 py-2 text-sm'
                    >
                        <option value=''>Pilih parameter...</option>
                        {parameterOptions.map((option) => (
                            <option key={option.id} value={option.id}>{option.name}</option>
                        ))}
                    </select>
                    {errors.parameter_id && <p className='text-xs text-destructive'>{errors.parameter_id}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='ttp-method'>Metode</Label>
                    <select
                        id='ttp-method'
                        value={data.method_id}
                        onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setData('method_id', e.target.value)}
                        className='w-full rounded-md border bg-background px-3 py-2 text-sm'
                    >
                        <option value=''>{isLoadingMethods ? 'Memuat metode...' : 'Tanpa metode'}</option>
                        {availableMethods.map((option) => (
                            <option key={option.id} value={option.id}>{option.code} - {option.name}</option>
                        ))}
                    </select>
                    {errors.method_id && <p className='text-xs text-destructive'>{errors.method_id}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='ttp-unit'>Satuan</Label>
                    <Input
                        id='ttp-unit'
                        value={data.unit}
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('unit', e.target.value)}
                        placeholder='e.g. mg/L'
                    />
                    {errors.unit && <p className='text-xs text-destructive'>{errors.unit}</p>}
                </div>

                <div className='space-y-1.5'>
                    <Label htmlFor='ttp-sort'>Urutan</Label>
                    <Input
                        id='ttp-sort'
                        type='number'
                        min='0'
                        value={data.sort_order}
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => setData('sort_order', e.target.value)}
                    />
                    {errors.sort_order && <p className='text-xs text-destructive'>{errors.sort_order}</p>}
                </div>

                <div className='col-span-full space-y-1.5'>
                    <Label htmlFor='ttp-description'>Keterangan</Label>
                    <Textarea
                        id='ttp-description'
                        rows={3}
                        value={data.description}
                        onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setData('description', e.target.value)}
                        placeholder='Catatan tambahan...'
                    />
                    {errors.description && <p className='text-xs text-destructive'>{errors.description}</p>}
                </div>

                <div className='col-span-full flex items-center gap-2'>
                    <Checkbox
                        id='ttp-required'
                        checked={data.is_required}
                        onCheckedChange={(value: boolean | 'indeterminate') => setData('is_required', !!value)}
                    />
                    <Label htmlFor='ttp-required' className='cursor-pointer font-normal'>
                        Parameter wajib untuk template ini
                    </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...' : param ? 'Simpan Perubahan' : 'Simpan'}
                </Button>
            </div>
        </form>
    )
}
