"use client"

import { useState } from "react"
import {
    useFormContext,
    useController,
    type FieldValues,
    type FieldPath,
} from "react-hook-form"
import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query"
import {
    Check,
    ChevronFirst,
    ChevronLast,
    ChevronLeft,
    ChevronRight,
    Edit2,
    MoreHorizontal,
    Plus,
    RefreshCcw,
    Search,
    Trash2,
    X,
} from "lucide-react"

import { useAuthApi } from "@/shared/useApi"
import { QUICK_NOTE_ROUTES } from "@garage/api"
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
} from "@/shared/components/ui/sheet"
import { Button } from "@/shared/components/ui/button"
import { Input } from "@/shared/components/ui/input"
import {
    Field,
    FieldLabel,
    FieldError,
} from "@/shared/components/ui/field"
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from "@/shared/components/ui/dropdown-menu"
import {
    Tooltip,
    TooltipContent,
    TooltipTrigger,
} from "@/shared/components/ui/tooltip"
import { cn } from "@/shared/lib/utils"

type QuickNote = {
    id: number
    description: string
}

type QuickNotesPage = {
    data: QuickNote[]
    meta: {
        current_page: number
        last_page: number
        per_page: number
        total: number
    }
}

type RhfQuickNotesFieldProps<
    TValues extends FieldValues,
    TName extends FieldPath<TValues>,
> = {
    name: TName
    label?: string
    description?: string
    required?: boolean
    disabled?: boolean
    placeholder?: string
}

function extractPage(response: unknown): QuickNotesPage {
    const r = response as any
    return {
        data: Array.isArray(r?.data?.data)
            ? r.data.data
            : Array.isArray(r?.data)
              ? r.data
              : [],
        meta: r?.data?.meta ?? r?.meta ?? {
            current_page: 1,
            last_page: 1,
            per_page: 15,
            total: 0,
        },
    }
}

function QuickNotesSheet({
    open,
    onOpenChange,
    selected,
    onToggle,
}: {
    open: boolean
    onOpenChange: (v: boolean) => void
    selected: string[]
    onToggle: (description: string) => void
}) {
    const api = useAuthApi()
    const queryClient = useQueryClient()

    const [page, setPage] = useState(1)
    const [search, setSearch] = useState("")
    const [creating, setCreating] = useState(false)
    const [newDescription, setNewDescription] = useState("")
    const [editingId, setEditingId] = useState<number | null>(null)
    const [editingText, setEditingText] = useState("")

    const queryKey = [QUICK_NOTE_ROUTES.INDEX, { page, search }]

    const { data, isLoading } = useQuery<QuickNotesPage>({
        queryKey,
        queryFn: async () => {
            const res = await api.quickNotes.list({
                page,
                ...(search ? { search } : {}),
            })
            return extractPage(res)
        },
        enabled: open,
        staleTime: 30_000,
    })

    const notes = data?.data ?? []
    const meta = data?.meta

    const invalidate = () =>
        queryClient.invalidateQueries({ queryKey: [QUICK_NOTE_ROUTES.INDEX] })

    const createMutation = useMutation({
        mutationFn: (description: string) =>
            api.quickNotes.create({ description }),
        onSuccess: () => {
            invalidate()
            setCreating(false)
            setNewDescription("")
        },
    })

    const updateMutation = useMutation({
        mutationFn: ({ id, description }: { id: number; description: string }) =>
            api.quickNotes.update(String(id), { description }),
        onSuccess: () => {
            invalidate()
            setEditingId(null)
            setEditingText("")
        },
    })

    const deleteMutation = useMutation({
        mutationFn: (id: number) =>
            api.quickNotes.destroy(String(id)),
        onSuccess: () => invalidate(),
    })

    function handleCreate() {
        const text = newDescription.trim()
        if (!text) return
        createMutation.mutate(text)
    }

    function handleUpdate(id: number) {
        const text = editingText.trim()
        if (!text) return
        updateMutation.mutate({ id, description: text })
    }

    function startEdit(note: QuickNote) {
        setEditingId(note.id)
        setEditingText(note.description)
    }

    const totalPages = meta?.last_page ?? 1
    const from = meta ? (meta.current_page - 1) * meta.per_page + 1 : 0
    const to = meta ? Math.min(meta.current_page * meta.per_page, meta.total) : 0

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent side="right" className="flex w-105 flex-col gap-0 p-0 sm:w-120">
                <SheetHeader className="flex flex-row items-center justify-between border-b px-4 py-3">
                    <SheetTitle className="text-base font-semibold">Quick Notes</SheetTitle>
                </SheetHeader>

                <div className="border-b px-3 py-2 flex gap-1 items-center">
                    <div className="relative grow">
                        <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                        <Input
                            placeholder="Search..."
                            value={search}
                            onChange={(e) => {
                                setSearch(e.target.value)
                                setPage(1)
                            }}
                            className="pl-9 h-9"
                        />
                    </div>
                    <Button
                        type="button"
                        size="sm"
                        onClick={() => {
                            setCreating(true)
                            setEditingId(null)
                        }}
                    >
                        <Plus className="h-3.5 w-3.5" />
                        Add
                    </Button>
                </div>

                {creating && (
                    <div className="border-b px-3 py-2">
                        <div className="flex items-center gap-2">
                            <Input
                                autoFocus
                                placeholder="New quick note..."
                                value={newDescription}
                                onChange={(e) => setNewDescription(e.target.value)}
                                onKeyDown={(e) => {
                                    if (e.key === "Enter") { e.preventDefault(); handleCreate() }
                                    if (e.key === "Escape") { setCreating(false); setNewDescription("") }
                                }}
                                className="h-8 text-sm"
                            />
                            <Button
                                type="button"
                                size="sm"
                                disabled={createMutation.isPending || !newDescription.trim()}
                                onClick={handleCreate}
                            >
                                Save
                            </Button>
                            <Button
                                type="button"
                                size="sm"
                                variant="ghost"
                                onClick={() => { setCreating(false); setNewDescription("") }}
                            >
                                <X className="h-3.5 w-3.5" />
                            </Button>
                        </div>
                    </div>
                )}

                <div className="flex-1 overflow-y-auto">
                    {isLoading ? (
                        <div className="flex items-center justify-center py-8 text-sm text-muted-foreground">
                            Loading...
                        </div>
                    ) : notes.length === 0 ? (
                        <div className="flex items-center justify-center py-8 text-sm text-muted-foreground">
                            No quick notes found.
                        </div>
                    ) : (
                        notes.map((note) => {
                            const isSelected = selected.includes(note.description)
                            const isEditing = editingId === note.id

                            if (isEditing) {
                                return (
                                    <div key={note.id} className="flex items-center gap-2 border-b px-4 py-2">
                                        <Input
                                            autoFocus
                                            value={editingText}
                                            onChange={(e) => setEditingText(e.target.value)}
                                            onKeyDown={(e) => {
                                                if (e.key === "Enter") { e.preventDefault(); handleUpdate(note.id) }
                                                if (e.key === "Escape") { setEditingId(null); setEditingText("") }
                                            }}
                                            className="h-8 flex-1 text-sm"
                                        />
                                        <Button
                                            type="button"
                                            size="sm"
                                            disabled={updateMutation.isPending || !editingText.trim()}
                                            onClick={() => handleUpdate(note.id)}
                                        >
                                            Save
                                        </Button>
                                        <Button
                                            type="button"
                                            size="sm"
                                            variant="ghost"
                                            onClick={() => { setEditingId(null); setEditingText("") }}
                                        >
                                            <X className="h-3.5 w-3.5" />
                                        </Button>
                                    </div>
                                )
                            }

                            return (
                                <div
                                    key={note.id}
                                    className={cn(
                                        "flex cursor-pointer items-center justify-between border-b px-4 py-3 transition-colors hover:bg-muted/50",
                                        isSelected && "bg-primary/5",
                                    )}
                                    onClick={() => onToggle(note.description)}
                                    role="button"
                                    tabIndex={0}
                                    onKeyDown={(e) => {
                                        if (e.key === "Enter" || e.key === " ") {
                                            e.preventDefault()
                                            onToggle(note.description)
                                        }
                                    }}
                                >
                                    <div className="flex items-center gap-3 flex-1 min-w-0">
                                        <div className={cn(
                                            "flex h-4 w-4 shrink-0 items-center justify-center",
                                        )}>
                                            {isSelected && (
                                                <Check className="h-4 w-4 text-primary" />
                                            )}
                                        </div>
                                        <span className="truncate text-sm">{note.description}</span>
                                    </div>
                                    <DropdownMenu>
                                        <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                                            <Button
                                                type="button"
                                                variant="ghost"
                                                size="icon"
                                                className="h-7 w-7 shrink-0"
                                            >
                                                <MoreHorizontal className="h-4 w-4" />
                                                <span className="sr-only">Actions</span>
                                            </Button>
                                        </DropdownMenuTrigger>
                                        <DropdownMenuContent align="end">
                                            <DropdownMenuItem
                                                onClick={(e) => {
                                                    e.stopPropagation()
                                                    startEdit(note)
                                                }}
                                            >
                                                <Edit2 className="mr-2 h-3.5 w-3.5" />
                                                Edit
                                            </DropdownMenuItem>
                                            <DropdownMenuItem
                                                className="text-destructive focus:text-destructive"
                                                onClick={(e) => {
                                                    e.stopPropagation()
                                                    deleteMutation.mutate(note.id)
                                                }}
                                            >
                                                <Trash2 className="mr-2 h-3.5 w-3.5" />
                                                Delete
                                            </DropdownMenuItem>
                                        </DropdownMenuContent>
                                    </DropdownMenu>
                                </div>
                            )
                        })
                    )}
                </div>

                {meta && meta.total > 0 && (
                    <div className="flex items-center justify-between border-t px-4 py-2 text-sm text-muted-foreground">
                        <span>
                            {from}-{to} of {meta.total}
                        </span>
                        <div className="flex items-center gap-1">
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7"
                                disabled={page <= 1}
                                onClick={() => setPage(1)}
                            >
                                <ChevronFirst className="h-4 w-4" />
                            </Button>
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7"
                                disabled={page <= 1}
                                onClick={() => setPage((p) => p - 1)}
                            >
                                <ChevronLeft className="h-4 w-4" />
                            </Button>
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7"
                                disabled={page >= totalPages}
                                onClick={() => setPage((p) => p + 1)}
                            >
                                <ChevronRight className="h-4 w-4" />
                            </Button>
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7"
                                disabled={page >= totalPages}
                                onClick={() => setPage(totalPages)}
                            >
                                <ChevronLast className="h-4 w-4" />
                            </Button>
                        </div>
                    </div>
                )}
            </SheetContent>
        </Sheet>
    )
}

export function RhfQuickNotesField<
    TValues extends FieldValues,
    TName extends FieldPath<TValues>,
>({
    name,
    label = "Quick Notes",
    description,
    required,
    disabled,
    placeholder = "Enter note...",
}: RhfQuickNotesFieldProps<TValues, TName>) {
    const { control } = useFormContext<TValues>()
    const { field, fieldState: { error } } = useController({ name, control, disabled })

    const [sheetOpen, setSheetOpen] = useState(false)

    const notes: string[] = Array.isArray(field.value) ? field.value : []

    function updateAt(index: number, value: string) {
        const next = [...notes]
        next[index] = value
        field.onChange(next)
    }

    function addLine() {
        field.onChange([...notes, ""])
    }

    function removeLine(index: number) {
        field.onChange(notes.filter((_, i) => i !== index))
    }

    function toggleQuickNote(description: string) {
        const exists = notes.includes(description)
        if (exists) {
            field.onChange(notes.filter((r) => r !== description))
        } else {
            field.onChange([...notes, description])
        }
    }

    return (
        <Field data-invalid={!!error || undefined}>
            {label && (
                <FieldLabel>
                    {label}
                    {required && (
                        <span className="text-destructive ms-0.5">*</span>
                    )}
                </FieldLabel>
            )}

            <div className="flex flex-col rounded-md border divide-y overflow-hidden">
                {notes.map((note, index) => (
                    <div key={index} className="flex items-center gap-2 px-3 py-2 bg-background">
                        <input
                            type="text"
                            value={note}
                            onChange={(e) => updateAt(index, e.target.value)}
                            placeholder={placeholder}
                            disabled={disabled}
                            className="flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
                        />
                        <button
                            type="button"
                            disabled={disabled}
                            onClick={() => removeLine(index)}
                            className="shrink-0 rounded-full p-0.5 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-40"
                            aria-label="Remove note"
                        >
                            <X className="h-4 w-4" />
                        </button>
                    </div>
                ))}

                {notes.length === 0 && (
                    <div className="px-3 py-2 text-sm text-muted-foreground italic">
                        No notes added yet.
                    </div>
                )}

                <div className="flex items-center justify-between px-3 py-2 bg-muted/30">
                    <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        disabled={disabled}
                        onClick={addLine}
                        className="h-7 gap-1.5 text-xs text-primary hover:text-primary"
                    >
                        <Plus className="h-3.5 w-3.5" />
                        New Line
                    </Button>

                    <Tooltip>
                        <TooltipTrigger asChild>
                            <Button
                                type="button"
                                variant="default"
                                size="icon"
                                disabled={disabled}
                                onClick={() => setSheetOpen(true)}
                                className="h-8 w-8 rounded-full"
                                aria-label="Pick from Quick Notes"
                            >
                                <RefreshCcw className="h-4 w-4" />
                            </Button>
                        </TooltipTrigger>
                        <TooltipContent side="left">Quick Notes</TooltipContent>
                    </Tooltip>
                </div>
            </div>

            {error && <FieldError>{error.message}</FieldError>}
            {description && !error && (
                <p className="text-xs text-muted-foreground">{description}</p>
            )}

            <QuickNotesSheet
                open={sheetOpen}
                onOpenChange={setSheetOpen}
                selected={notes}
                onToggle={toggleQuickNote}
            />
        </Field>
    )
}
