import { useDroppable } from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { useState } from 'react';
import { MoreHorizontal, Pencil, Plus, Trash2, ChevronUp, ChevronRight, ChevronDown } from 'lucide-react';
import type { CardResponse, ColumnWithCardsResponse } from '@/client';
import { cardCreate, cardDelete, cardUpdate, columnDelete, columnUpdate } from '@/client';
import { useProject } from '@/contexts';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { toast } from 'sonner';
import { KanbanCard } from './KanbanCard';

interface KanbanColumnProps {
    columnData: ColumnWithCardsResponse;
    onCardAdded?: () => void;
}

// ─── Card Edit Dialog ─────────────────────────────────────────────────────────

function CardDialog({
    card,
    columnId,
    position: _position,
    onClose,
    onSaved,
}: {
    card?: CardResponse;
    columnId: string;
    position: number;
    onClose: () => void;
    onSaved: () => void;
}) {
    const { project } = useProject();
    const [title, setTitle] = useState(card?.title ?? '');
    const [description, setDescription] = useState(card?.description ?? '');
    const [priority, setPriority] = useState<'high' | 'medium' | 'low' | ''>(
        (card?.priority as 'high' | 'medium' | 'low') ?? '',
    );
    const [loading, setLoading] = useState(false);

    const isEdit = !!card;

    const handleSubmit = async () => {
        if (!project?.name || !title.trim()) return;
        setLoading(true);
        try {
            if (isEdit) {
                await cardUpdate({
                    path: { project_name: project.name, card_id: card.id },
                    body: {
                        title: title.trim(),
                        description: description.trim() || undefined,
                        priority: priority || undefined,
                    },
                });
            } else {
                await cardCreate({
                    path: { project_name: project.name },
                    body: { title: title.trim(), column_id: columnId },
                });
            }
            onSaved();
            onClose();
        } catch {
            toast.error(`Failed to ${isEdit ? 'update' : 'create'} card`);
        } finally {
            setLoading(false);
        }
    };

    const handleDelete = async () => {
        if (!project?.name || !card) return;
        setLoading(true);
        try {
            await cardDelete({ path: { project_name: project.name, card_id: card.id } });
            onSaved();
            onClose();
        } catch {
            toast.error('Failed to delete card');
        } finally {
            setLoading(false);
        }
    };

    return (
        <Dialog open onOpenChange={(o) => !o && onClose()}>
            <DialogContent className="max-w-sm">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2 text-[15px] font-semibold">
                        {isEdit ? (
                            <>
                                <Pencil className="h-4 w-4 text-[#18181B]" />
                                Edit Card
                            </>
                        ) : (
                            <>
                                <Plus className="h-4 w-4 text-[#18181B]" />
                                Add Card
                            </>
                        )}
                    </DialogTitle>
                </DialogHeader>

                <div className="space-y-4 py-2">
                    {/* Title */}
                    <div className="space-y-1.5">
                        <Label className="text-[12px] font-semibold uppercase tracking-[0.08em] text-[#71717A]">
                            Title
                        </Label>
                        <Input
                            value={title}
                            onChange={(e) => setTitle(e.target.value)}
                            placeholder="Card title"
                            className="h-10 border-[#E4E4E7] focus:border-[#D4D4D8]"
                            autoFocus
                        />
                    </div>

                    {/* Description */}
                    <div className="space-y-1.5">
                        <Label className="text-[12px] font-semibold uppercase tracking-[0.08em] text-[#71717A]">
                            Description
                        </Label>
                        <Input
                            value={description}
                            onChange={(e) => setDescription(e.target.value)}
                            placeholder="Optional"
                            className="h-10 border-[#E4E4E7] focus:border-[#D4D4D8]"
                        />
                    </div>

                    {/* Priority */}
                    <div className="space-y-1.5">
                        <Label className="text-[12px] font-semibold uppercase tracking-[0.08em] text-[#71717A]">
                            Priority
                        </Label>
                        <div className="flex gap-2">
                            <button
                                type="button"
                                onClick={() => setPriority(priority === 'high' ? '' : 'high')}
                                className={`flex-1 rounded-lg border py-2 text-[13px] font-medium flex items-center justify-center gap-1.5 transition-colors cursor-pointer ${
                                    priority === 'high'
                                        ? 'border-red-400 bg-red-50 text-red-600'
                                        : 'border-[#E4E4E7] bg-white text-[#71717A] hover:border-red-300 hover:text-red-500'
                                }`}
                            >
                                <ChevronUp className="h-3.5 w-3.5" /> High
                            </button>
                            <button
                                type="button"
                                onClick={() => setPriority(priority === 'medium' ? '' : 'medium')}
                                className={`flex-1 rounded-lg border py-2 text-[13px] font-medium flex items-center justify-center gap-1.5 transition-colors cursor-pointer ${
                                    priority === 'medium'
                                        ? 'border-amber-400 bg-amber-50 text-amber-600'
                                        : 'border-[#E4E4E7] bg-white text-[#71717A] hover:border-amber-300 hover:text-amber-500'
                                }`}
                            >
                                <ChevronRight className="h-3.5 w-3.5" /> Medium
                            </button>
                            <button
                                type="button"
                                onClick={() => setPriority(priority === 'low' ? '' : 'low')}
                                className={`flex-1 rounded-lg border py-2 text-[13px] font-medium flex items-center justify-center gap-1.5 transition-colors cursor-pointer ${
                                    priority === 'low'
                                        ? 'border-blue-400 bg-blue-50 text-blue-600'
                                        : 'border-[#E4E4E7] bg-white text-[#71717A] hover:border-blue-300 hover:text-blue-500'
                                }`}
                            >
                                <ChevronDown className="h-3.5 w-3.5" /> Low
                            </button>
                        </div>
                    </div>

                    {/* Actions */}
                    <div className="flex items-center justify-between pt-2 border-t border-[#E4E4E7]">
                        {isEdit ? (
                            <button
                                type="button"
                                onClick={handleDelete}
                                disabled={loading}
                                className="px-3 py-2 rounded-lg text-[13px] font-medium text-[#DC2626] hover:bg-[rgba(220,38,38,0.08)] transition-colors disabled:opacity-50 cursor-pointer bg-transparent border-0"
                            >
                                Delete card
                            </button>
                        ) : (
                            <div />
                        )}
                        <div className="flex gap-2">
                            <button
                                type="button"
                                onClick={onClose}
                                className="px-4 py-2.5 rounded-lg border border-[#E4E4E7] bg-white text-[13px] font-medium text-[#27272A] hover:bg-[#F4F4F5] transition-colors cursor-pointer"
                            >
                                Cancel
                            </button>
                            <button
                                type="button"
                                onClick={handleSubmit}
                                disabled={loading || !title.trim()}
                                className="px-4 py-2.5 rounded-lg border border-[#D4D4D8] bg-[#18181B] text-[13px] font-medium text-white hover:bg-[#27272A] transition-colors disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
                            >
                                {loading ? '...' : isEdit ? 'Save' : 'Add Card'}
                            </button>
                        </div>
                    </div>
                </div>
            </DialogContent>
        </Dialog>
    );
}

// ─── Column Menu ──────────────────────────────────────────────────────────────

function ColumnMenu({
    columnId: _columnId,
    columnName: _columnName,
    onRename,
    onDelete,
}: {
    columnId: string;
    columnName: string;
    onRename: () => void;
    onDelete: () => void;
}) {
    return (
        <div className="flex flex-col divide-y divide-[#E4E4E7]">
            <button
                type="button"
                onClick={onRename}
                className="flex items-center gap-2 px-3 py-2 text-[13px] text-[#27272A] hover:bg-[#F4F4F5] cursor-pointer bg-transparent border-0 text-left transition-colors rounded-t-lg"
            >
                <Pencil className="h-3.5 w-3.5" />
                Rename column
            </button>
            <button
                type="button"
                onClick={onDelete}
                className="flex items-center gap-2 px-3 py-2 text-[13px] text-[#DC2626] hover:bg-[rgba(220,38,38,0.06)] cursor-pointer bg-transparent border-0 text-left transition-colors rounded-b-lg"
            >
                <Trash2 className="h-3.5 w-3.5" />
                Delete column
            </button>
        </div>
    );
}

// ─── Kanban Column ───────────────────────────────────────────────────────────

export function KanbanColumn({ columnData, onCardAdded }: KanbanColumnProps) {
    const { column, cards } = columnData;
    const { project } = useProject();
    const [showMenu, setShowMenu] = useState(false);
    const [editingCard, setEditingCard] = useState<CardResponse | undefined>(undefined);
    const [addingCard, setAddingCard] = useState(false);
    const [renameOpen, setRenameOpen] = useState(false);
    const [newColName, setNewColName] = useState(column.name);
    const [renaming, setRenaming] = useState(false);

    const { setNodeRef, isOver } = useDroppable({
        id: column.id,
        data: { type: 'Column', column },
    });

    const wipExceeded = column.wip_limit != null && cards.length > column.wip_limit;

    const handleRename = async () => {
        if (!project?.name || !newColName.trim()) return;
        setRenaming(true);
        try {
            await columnUpdate({
                path: { project_name: project.name, column_id: column.id },
                body: { name: newColName.trim() },
            });
            setRenameOpen(false);
        } catch {
            toast.error('Failed to rename column');
        } finally {
            setRenaming(false);
        }
    };

    const handleDelete = async () => {
        if (!project?.name) return;
        if (!confirm(`Delete column "${column.name}"? Cards will be deleted.`)) return;
        try {
            await columnDelete({ path: { project_name: project.name, column_id: column.id } });
            onCardAdded?.();
        } catch {
            toast.error('Failed to delete column');
        }
    };

    return (
        <>
            <div
                className={`flex w-72 flex-shrink-0 flex-col rounded-xl border bg-[#FAFAFA] ${
                    isOver ? 'ring-2 ring-[#18181B]/30 bg-[#F4F4F5]' : 'border-[#E4E4E7]'
                }`}
                style={{
                    borderLeftColor: column.color ?? undefined,
                    borderLeftWidth: column.color ? '3px' : undefined,
                }}
            >
                {/* Header */}
                <div className="flex items-center justify-between px-3 py-2.5">
                    <div className="flex items-center gap-2">
                        <span className="text-[13px] font-semibold text-[#18181B]">{column.name}</span>
                        <span
                            className={`inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[11px] font-medium ${
                                wipExceeded
                                    ? 'bg-[rgba(220,38,38,0.08)] text-[#DC2626]'
                                    : 'bg-[#F4F4F5] text-[#71717A]'
                            }`}
                        >
                            {cards.length}
                            {column.wip_limit != null && ` / ${column.wip_limit}`}
                        </span>
                    </div>
                    <div className="relative">
                        <button
                            type="button"
                            onClick={() => setShowMenu(!showMenu)}
                            className="flex h-6 w-6 items-center justify-center rounded-md hover:bg-[#E4E4E7] cursor-pointer bg-transparent border-0 transition-colors"
                        >
                            <MoreHorizontal className="h-4 w-4 text-[#71717A]" />
                        </button>
                        {showMenu && (
                            <div className="absolute right-0 top-full mt-1 z-20 w-44 rounded-lg border border-[#E4E4E7] bg-white shadow-lg overflow-hidden">
                                <ColumnMenu
                                    columnId={column.id}
                                    columnName={column.name}
                                    onRename={() => {
                                        setNewColName(column.name);
                                        setRenameOpen(true);
                                        setShowMenu(false);
                                    }}
                                    onDelete={handleDelete}
                                />
                            </div>
                        )}
                    </div>
                </div>

                {/* Cards */}
                <div
                    ref={setNodeRef}
                    className="flex flex-1 flex-col gap-2 overflow-y-auto px-2 pb-2"
                >
                    <SortableContext items={cards.map((c) => c.id)} strategy={verticalListSortingStrategy}>
                        {cards.map((card) => (
                            <KanbanCard
                                key={card.id}
                                card={card}
                                onEdit={setEditingCard}
                            />
                        ))}
                    </SortableContext>
                    {cards.length === 0 && (
                        <div className="flex flex-1 items-center justify-center py-8 text-[12px] text-[#71717A]">
                            No cards
                        </div>
                    )}
                    {/* Add card at bottom */}
                    <button
                        type="button"
                        onClick={() => setAddingCard(true)}
                        className="flex w-full items-center gap-1.5 px-2 py-1.5 rounded-md text-[12px] text-[#71717A] hover:bg-[#E4E4E7] hover:text-[#27272A] transition-colors cursor-pointer bg-transparent border-0"
                    >
                        <Plus className="h-3.5 w-3.5" />
                        Add card
                    </button>
                </div>
            </div>

            {/* Edit card dialog */}
            {editingCard && (
                <CardDialog
                    card={editingCard}
                    columnId={column.id}
                    position={cards.findIndex((c) => c.id === editingCard.id)}
                    onClose={() => setEditingCard(undefined)}
                    onSaved={onCardAdded ?? (() => {})}
                />
            )}

            {/* Add card dialog */}
            {addingCard && (
                <CardDialog
                    columnId={column.id}
                    position={cards.length}
                    onClose={() => setAddingCard(false)}
                    onSaved={onCardAdded ?? (() => {})}
                />
            )}

            {/* Rename column dialog */}
            <Dialog open={renameOpen} onOpenChange={setRenameOpen}>
                <DialogContent className="max-w-xs">
                    <DialogHeader>
                        <DialogTitle className="flex items-center gap-2 text-[15px] font-semibold">
                            <Pencil className="h-4 w-4 text-[#18181B]" />
                            Rename Column
                        </DialogTitle>
                    </DialogHeader>
                    <div className="space-y-4 py-2">
                        <div className="space-y-1.5">
                            <Label className="text-[12px] font-semibold uppercase tracking-[0.08em] text-[#71717A]">
                                Name
                            </Label>
                            <Input
                                value={newColName}
                                onChange={(e) => setNewColName(e.target.value)}
                                className="h-10 border-[#E4E4E7] focus:border-[#D4D4D8]"
                                autoFocus
                                onKeyDown={(e) => {
                                    if (e.key === 'Enter') handleRename();
                                }}
                            />
                        </div>
                        <div className="flex justify-end gap-2">
                            <button
                                type="button"
                                onClick={() => setRenameOpen(false)}
                                className="px-4 py-2.5 rounded-lg border border-[#E4E4E7] bg-white text-[13px] font-medium text-[#27272A] hover:bg-[#F4F4F5] transition-colors cursor-pointer"
                            >
                                Cancel
                            </button>
                            <button
                                type="button"
                                onClick={handleRename}
                                disabled={renaming || !newColName.trim()}
                                className="px-4 py-2.5 rounded-lg border border-[#D4D4D8] bg-[#18181B] text-[13px] font-medium text-white hover:bg-[#27272A] transition-colors disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
                            >
                                {renaming ? '...' : 'Rename'}
                            </button>
                        </div>
                    </div>
                </DialogContent>
            </Dialog>
        </>
    );
}
