import {ArrowDown, ArrowUp, Check, LucideIcon, Pen, Trash2, X} from "lucide-react";
import React, {ChangeEvent, useState} from "react";
import IconContainer from "@/components/ui/IconContainer";

interface ListItemProps {
    onClick: () => void;
    selectedId: number | string;
    id: number | string;
    icon?: LucideIcon;
    numericalIdentifier?: number;
    isEditable?: boolean;
    text: string;
    handleDelete?: (itemId: string) => void;
    handleUpdate?: (itemId: string, newValue: string, subNewValue: number) => void;
    onReorder?: (itemId: string, newOrder: number) => void;
}

export default function ListItem(
    {
        text,
        selectedId,
        id,
        icon,
        onClick,
        isEditable = false,
        handleDelete,
        numericalIdentifier,
        handleUpdate,
        onReorder
    }: ListItemProps): React.JSX.Element {

    const [editMode, setEditMode] = useState<boolean>(false);
    const [newName, setNewName] = useState<string>('');
    const [newChapterOrder, setNewChapterOrder] = useState<number>(numericalIdentifier ?? 0);

    function handleEdit(itemName: string): void {
        setNewName(itemName)
        setEditMode(true)
    }

    function handleSave(): void {
        if (!handleUpdate) return;
        handleUpdate(String(id), newName, newChapterOrder)
        setEditMode(false);
    }

    function moveItem(direction: "up" | "down"): void {
        const nextOrder: number = direction === "up" ? newChapterOrder - 1 : newChapterOrder + 1;
        if (nextOrder < 0) return;
        setNewChapterOrder(nextOrder);
        if (onReorder) {
            onReorder(String(id), nextOrder);
        }
    }

    return (
        <li className={`group relative flex items-center p-3 rounded-xl transition-colors duration-200 ${
            selectedId === id
                ? 'bg-tertiary text-text-primary'
                : 'hover:bg-tertiary'
        }`}>
            {(numericalIdentifier != null && newChapterOrder >= 0) && (
                <span className="text-muted text-xs w-5 h-5 rounded-md bg-tertiary text-center leading-5 shrink-0 mr-2">
                    {newChapterOrder}
                </span>
            )}
            {icon && (
                <IconContainer icon={icon} size="sm" shape="square"/>
            )}
            <div className="flex items-center w-full gap-2">
                {editMode ? (
                    <>
                        <input
                            type="text"
                            value={newName || text}
                            onChange={(e: ChangeEvent<HTMLInputElement>): void => setNewName(e.target.value)}
                            autoFocus
                            className="flex-1 bg-transparent text-sm font-medium text-text-primary outline-none min-w-0"
                        />
                        <div className="flex shrink-0">
                            <button onClick={(): void => moveItem('up')} disabled={newChapterOrder <= 0}
                                    className="text-muted hover:text-text-primary disabled:opacity-30 p-0.5">
                                <ArrowUp className="w-3.5 h-3.5" strokeWidth={1.75}/>
                            </button>
                            <button onClick={(): void => moveItem('down')}
                                    className="text-muted hover:text-text-primary p-0.5">
                                <ArrowDown className="w-3.5 h-3.5" strokeWidth={1.75}/>
                            </button>
                            <button onClick={handleSave}
                                    className="text-primary hover:text-primary/80 p-0.5">
                                <Check className="w-3.5 h-3.5" strokeWidth={1.75}/>
                            </button>
                            <button onClick={(): void => setEditMode(false)}
                                    className="text-muted hover:text-text-primary p-0.5">
                                <X className="w-3.5 h-3.5" strokeWidth={1.75}/>
                            </button>
                        </div>
                    </>
                ) : (
                    <span
                        className="cursor-pointer text-sm font-medium flex-1 group-hover:text-text-primary transition-colors"
                        onClick={onClick}>{text}</span>
                )}
                {!editMode && isEditable && (
                    <div className="absolute right-1 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
                        <button onClick={(): void => handleEdit(text)}
                                className="text-muted hover:text-text-primary p-1.5 rounded-lg hover:bg-secondary">
                            <Pen className="w-4 h-4" strokeWidth={1.75}/>
                        </button>
                        <button onClick={(): void => {
                            if (handleDelete) handleDelete(id.toString());
                        }}
                                className="text-muted hover:text-error p-1.5 rounded-lg hover:bg-error/10">
                            <Trash2 className="w-4 h-4" strokeWidth={1.75}/>
                        </button>
                    </div>
                )}
            </div>
        </li>
    )
}
