import { Head, router } from '@inertiajs/react'
import { useMemo, useState } from 'react'
import { toast } from 'sonner'
import { CheckSquare, Eye, Pencil } from 'lucide-react'
import { LimsAppLayout } from '@/layouts/lims-app-layout'
import { ResizableDrawer } from '@/components/common/ResizableDrawer'
import { Button } from '@ui/components/ui/button'
import { Input } from '@ui/components/ui/input'
import { Checkbox } from '@ui/components/ui/checkbox'
import { Badge } from '@ui/components/ui/badge'

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

interface AnalystRow {
    id: number
    name: string
    username: string
    email: string | null
    position_id: number
    branch_id: number | null
    branch_name: string
    assignments_count: number | string
}

interface AssignmentOption {
    id: number
    sample_type_id: number
    parameter_id: number
    analyst_user_id: number | null
    sample_type?: { id: number; code: string; name: string }
    parameter?: { id: number; code: string; name: string }
}

interface Props {
    filters: {
        branch_id?: string
        search?: string
    }
    branches: BranchOption[]
    analysts: AnalystRow[]
    assignmentOptions: AssignmentOption[]
}

function positionLabel(positionId: number): string {
    if (positionId === 11) return 'Analis'
    if (positionId === 72) return 'Analis Biologi'
    if (positionId === 74) return 'Analis Kimia'
    return `Posisi #${positionId}`
}

export default function AnalystAssignmentIndex({
    filters,
    branches,
    analysts,
    assignmentOptions,
}: Props) {
    const [isDrawerOpen, setIsDrawerOpen] = useState(false)
    const [drawerMode, setDrawerMode] = useState<'view' | 'manage'>('manage')
    const [selectedAnalyst, setSelectedAnalyst] = useState<AnalystRow | null>(null)
    const [selectedIds, setSelectedIds] = useState<number[]>([])
    const [searchOption, setSearchOption] = useState('')
    const [isSaving, setIsSaving] = useState(false)

    const analystNameMap = useMemo(
        () => new Map(analysts.map((row) => [row.id, row.name])),
        [analysts]
    )

    const filteredOptions = useMemo(() => {
        const term = searchOption.trim().toLowerCase()
        if (!term) return assignmentOptions

        return assignmentOptions.filter((item) => {
            const haystack = `${item.sample_type?.code ?? ''} ${item.sample_type?.name ?? ''} ${item.parameter?.name ?? ''}`.toLowerCase()
            return haystack.includes(term)
        })
    }, [assignmentOptions, searchOption])

    const visibleConflictCount = useMemo(() => {
        if (!selectedAnalyst) return 0
        return filteredOptions.filter(
            (item) =>
                item.analyst_user_id !== null
                && item.analyst_user_id !== selectedAnalyst.id
        ).length
    }, [filteredOptions, selectedAnalyst])

    const assignedToSelectedAnalyst = useMemo(() => {
        if (!selectedAnalyst) return []
        return assignmentOptions.filter((item) => item.analyst_user_id === selectedAnalyst.id)
    }, [assignmentOptions, selectedAnalyst])

    const filteredAssignedToSelectedAnalyst = useMemo(() => {
        const term = searchOption.trim().toLowerCase()
        if (!term) return assignedToSelectedAnalyst

        return assignedToSelectedAnalyst.filter((item) => {
            const haystack = `${item.sample_type?.code ?? ''} ${item.sample_type?.name ?? ''} ${item.parameter?.name ?? ''}`.toLowerCase()
            return haystack.includes(term)
        })
    }, [assignedToSelectedAnalyst, searchOption])

    function openDrawer(analyst: AnalystRow) {
        setDrawerMode('manage')
        setSelectedAnalyst(analyst)
        setSearchOption('')
        setSelectedIds(
            assignmentOptions
                .filter((item) => item.analyst_user_id === analyst.id)
                .map((item) => item.id)
        )
        setIsDrawerOpen(true)
    }

    function openViewDrawer(analyst: AnalystRow) {
        setDrawerMode('view')
        setSelectedAnalyst(analyst)
        setSearchOption('')
        setIsDrawerOpen(true)
    }

    function toggleId(id: number, checked: boolean) {
        setSelectedIds((prev) => {
            if (checked) return prev.includes(id) ? prev : [...prev, id]
            return prev.filter((x) => x !== id)
        })
    }

    function submit() {
        if (!selectedAnalyst) return

        router.patch(
            `/master-data/analyst-assignments/${selectedAnalyst.id}/sync`,
            { sample_type_parameter_ids: selectedIds },
            {
                preserveScroll: true,
                onStart: () => setIsSaving(true),
                onSuccess: () => {
                    toast.success(`Assignment untuk ${selectedAnalyst.name} berhasil disimpan.`)
                    setIsDrawerOpen(false)
                },
                onError: (errors) => toast.error(Object.values(errors)[0] ?? 'Terjadi kesalahan.'),
                onFinish: () => setIsSaving(false),
            }
        )
    }

    return (
        <LimsAppLayout>
            <Head title='Master Assignment Analis' />
            <div className='flex h-full flex-1 flex-col gap-4 p-4'>
                <div>
                    <h1 className='text-xl font-bold tracking-tight'>Master Assignment Analis</h1>
                    <p className='text-sm text-muted-foreground'>
                        Mapping one-to-many dari analis ke parameter per jenis sampel, dengan filter per cabang.
                    </p>
                </div>

                <div className='flex flex-wrap gap-2'>
                    <select
                        className='rounded-md border bg-background px-3 py-2 text-sm'
                        value={filters.branch_id ?? ''}
                        onChange={(e) =>
                            router.get(
                                '/master-data/analyst-assignments',
                                { ...filters, branch_id: e.target.value || undefined },
                                { preserveState: true, replace: true }
                            )
                        }
                    >
                        <option value=''>Semua Cabang</option>
                        {branches.map((branch) => (
                            <option key={branch.id} value={branch.id}>
                                {branch.code} - {branch.name}
                            </option>
                        ))}
                    </select>

                    <Input
                        className='w-full max-w-sm'
                        placeholder='Cari analis...'
                        value={filters.search ?? ''}
                        onChange={(e) =>
                            router.get(
                                '/master-data/analyst-assignments',
                                { ...filters, search: e.target.value || undefined },
                                { preserveState: true, replace: true }
                            )
                        }
                    />
                </div>

                <div className='overflow-hidden rounded-xl border bg-card'>
                    <table className='w-full text-sm'>
                        <thead className='bg-muted/40 text-left'>
                            <tr>
                                <th className='px-4 py-3'>Analis</th>
                                <th className='px-4 py-3'>Posisi</th>
                                <th className='px-4 py-3'>Cabang</th>
                                <th className='px-4 py-3'>Total Assignment</th>
                                <th className='px-4 py-3 text-right'>Aksi</th>
                            </tr>
                        </thead>
                        <tbody>
                            {analysts.map((row) => (
                                <tr key={row.id} className='border-t'>
                                    <td className='px-4 py-3'>
                                        <div className='font-medium'>{row.name}</div>
                                        <div className='text-xs text-muted-foreground'>{row.username}</div>
                                    </td>
                                    <td className='px-4 py-3'>{positionLabel(row.position_id)}</td>
                                    <td className='px-4 py-3'>{row.branch_name ?? '-'}</td>
                                    <td className='px-4 py-3'>
                                        <Badge variant='secondary'>{
                                            typeof row.assignments_count === 'string'
                                                ? Number(row.assignments_count)
                                                : row.assignments_count
                                        }</Badge>
                                    </td>
                                    <td className='px-4 py-3 text-right'>
                                        <div className='flex items-center justify-end gap-2'>
                                            <Button size='sm' variant='outline' className='gap-1' onClick={() => openViewDrawer(row)}>
                                                <Eye className='h-3.5 w-3.5' />
                                                Plotting
                                            </Button>
                                            <Button size='sm' variant='outline' className='gap-1' onClick={() => openDrawer(row)}>
                                                <Pencil className='h-3.5 w-3.5' />
                                                Kelola
                                            </Button>
                                        </div>
                                    </td>
                                </tr>
                            ))}
                            {analysts.length === 0 && (
                                <tr>
                                    <td colSpan={5} className='px-4 py-8 text-center text-muted-foreground'>
                                        Tidak ada analis untuk filter saat ini.
                                    </td>
                                </tr>
                            )}
                        </tbody>
                    </table>
                </div>
            </div>

            <ResizableDrawer
                open={isDrawerOpen}
                onOpenChange={setIsDrawerOpen}
                title={drawerMode === 'view' ? 'Plotting Parameter Analis' : 'Kelola Assignment Analis'}
                description={selectedAnalyst ? `${selectedAnalyst.name} - ${positionLabel(selectedAnalyst.position_id)}` : ''}
                defaultWidth={820}
                minWidth={680}
                maxWidth={1100}
            >
                {!selectedAnalyst ? null : drawerMode === 'view' ? (
                    <div className='space-y-4'>
                        <div className='flex items-center justify-between rounded-md border bg-muted/20 px-3 py-2 text-xs'>
                            <span>
                                Total plotting: <span className='font-semibold'>{assignedToSelectedAnalyst.length}</span>
                            </span>
                            <span>
                                Tampil: <span className='font-semibold'>{filteredAssignedToSelectedAnalyst.length}</span>
                            </span>
                        </div>

                        <Input
                            placeholder='Cari plotting...'
                            value={searchOption}
                            onChange={(e) => setSearchOption(e.target.value)}
                            className='h-9'
                        />

                        <div className='max-h-[65vh] overflow-auto rounded-lg border'>
                            <div className='grid grid-cols-12 border-b bg-muted/40 px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground'>
                                <div className='col-span-5'>Jenis Sampel</div>
                                <div className='col-span-7'>Parameter</div>
                            </div>

                            <div className='divide-y'>
                                {filteredAssignedToSelectedAnalyst.map((item) => (
                                    <div key={item.id} className='grid grid-cols-12 px-3 py-2 text-xs'>
                                        <div className='col-span-5 min-w-0 pr-2'>
                                            <p className='truncate font-medium leading-tight'>
                                                {item.sample_type?.code}
                                            </p>
                                            <p className='truncate text-muted-foreground leading-tight'>
                                                {item.sample_type?.name}
                                            </p>
                                        </div>
                                        <div className='col-span-7 min-w-0'>
                                            <p className='truncate font-medium leading-tight'>
                                                {item.parameter?.name}
                                            </p>
                                        </div>
                                    </div>
                                ))}
                            </div>

                            {filteredAssignedToSelectedAnalyst.length === 0 && (
                                <p className='py-6 text-center text-sm text-muted-foreground'>
                                    Belum ada parameter yang diplot untuk analis ini.
                                </p>
                            )}
                        </div>

                        <div className='flex justify-end pt-2'>
                            <Button variant='outline' onClick={() => setIsDrawerOpen(false)}>
                                Tutup
                            </Button>
                        </div>
                    </div>
                ) : (
                    <div className='space-y-4'>
                        <div className='space-y-1.5'>
                            <Input
                                placeholder='Cari jenis sampel / parameter...'
                                value={searchOption}
                                onChange={(e) => setSearchOption(e.target.value)}
                            />
                            <p className='text-xs text-muted-foreground'>
                                Pilih data parameter-per-jenis-sampel yang akan di-assign ke analis ini.
                            </p>
                        </div>

                        {visibleConflictCount > 0 && (
                            <div className='rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-800'>
                                Terdapat {visibleConflictCount} data yang sudah ter-assign ke analis lain (conflict).
                            </div>
                        )}

                        <div className='max-h-[55vh] space-y-2 overflow-auto rounded-lg border p-2'>
                            {filteredOptions.map((item) => {
                                const checked = selectedIds.includes(item.id)
                                const assignedToOther =
                                    item.analyst_user_id !== null
                                    && item.analyst_user_id !== selectedAnalyst.id

                                return (
                                    <label
                                        key={item.id}
                                        className={`flex cursor-pointer items-start gap-3 rounded-md border p-3 transition ${
                                            assignedToOther
                                                ? 'border-amber-300 bg-amber-50/40'
                                                : checked
                                                    ? 'border-blue-500 bg-blue-50/40'
                                                    : 'hover:bg-muted/30'
                                        }`}
                                    >
                                        <Checkbox
                                            checked={checked}
                                            onCheckedChange={(v) => toggleId(item.id, !!v)}
                                        />
                                        <div className='min-w-0 flex-1'>
                                            <div className='flex flex-wrap items-center gap-2'>
                                                <p className='font-medium leading-tight'>
                                                    {item.sample_type?.code} - {item.sample_type?.name}
                                                </p>
                                                {assignedToOther && (
                                                    <Badge variant='destructive' className='h-5 px-1.5 text-[10px] uppercase'>
                                                        Conflict
                                                    </Badge>
                                                )}
                                            </div>
                                            <p className='text-sm text-muted-foreground'>{item.parameter?.name}</p>
                                            {assignedToOther && (
                                                <p className='text-xs font-medium text-amber-700'>
                                                    Saat ini ter-assign ke: {analystNameMap.get(item.analyst_user_id!) ?? `User #${item.analyst_user_id}`}
                                                </p>
                                            )}
                                        </div>
                                    </label>
                                )
                            })}
                            {filteredOptions.length === 0 && (
                                <p className='py-6 text-center text-sm text-muted-foreground'>
                                    Tidak ada data yang cocok.
                                </p>
                            )}
                        </div>

                        <div className='flex justify-end gap-2 pt-2'>
                            <Button variant='outline' disabled={isSaving} onClick={() => setIsDrawerOpen(false)}>
                                Batal
                            </Button>
                            <Button className='gap-2' disabled={isSaving} onClick={submit}>
                                <CheckSquare className='h-4 w-4' />
                                {isSaving ? 'Menyimpan...' : 'Simpan Assignment'}
                            </Button>
                        </div>
                    </div>
                )}
            </ResizableDrawer>
        </LimsAppLayout>
    )
}
