import { type Component, createSignal, createEffect, onMount, For, Show, Suspense, lazy } from "solid-js";
import { addTask, calculateDateFromUrgency, calculateUrgencyFromDate, store, upsertTagDefinition, type TaskTemplate, currentTaskContext } from "@/store";
import { Search, Command, Clock, ArrowUpCircle, Copy, ChevronDown, Gauge, RotateCcw } from "lucide-solid";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { TextField, TextFieldInput } from "@/components/ui/textfield";
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select";
import { TagPicker } from "@/components/TagPicker";
import { useTheme } from "./ThemeProvider";
import { getThemeAdjustedColor } from "@/lib/colors";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { toast } from "solid-sonner";
import { PRIORITY_OPTIONS, URGENCY_OPTIONS, SIZE_OPTIONS } from "@/lib/constants";

const TaskEditor = lazy(() => import("./TaskEditor").then(m => ({ default: m.TaskEditor })));

interface QuickEntryFormProps {
    onSuccess?: () => void;
    autoFocus?: boolean;
    initialTitle?: string;
    initialTags?: string[];
}

// Global state for QuickEntry persistence
const [input, setInput] = createSignal("");
const [priority, setPriority] = createSignal<string>("");
const [urgency, setUrgency] = createSignal<string>("");
const [tags, setTags] = createSignal<string[]>([]);
const [description, setDescription] = createSignal("");
const [size, setSize] = createSignal<string>("3");
const [dateString, setDateString] = createSignal<string>("");
const [showValidation, setShowValidation] = createSignal(false);

let lastParsedTags: string[] = [];

const resetQuickEntryState = () => {
    setInput("");
    setPriority("");
    setUrgency("");
    setTags([]);
    setDescription("");
    setSize("3");
    setDateString("");
    setShowValidation(false);
    lastParsedTags = [];
};

export const QuickEntryForm: Component<QuickEntryFormProps> = (props) => {
    const { resolvedTheme } = useTheme();

    const [editorInstance, setEditorInstance] = createSignal<any>(null);

    let inputRef: HTMLInputElement | undefined;

    onMount(() => {
        if (props.autoFocus) {
            setTimeout(() => inputRef?.focus(), 100);
        }
        if (props.initialTitle && !input()) {
            setInput(props.initialTitle);
        }
    });

    // Reactive sync from props (handles context changes while open)
    createEffect(() => {
        const initial = props.initialTags || [];
        if (initial.length > 0) {
            setTags(prev => {
                // Merge initial tags if not already present
                const next = [...prev];
                initial.forEach(t => {
                    if (!next.includes(t)) next.push(t);
                });
                return next;
            });
        }
    });

    // Reactive shorthand parsing
    createEffect(() => {
        const text = input();

        const pMatch = text.match(/\/p(\d+)/);
        if (pMatch) {
            const val = Math.min(10, Math.max(1, parseInt(pMatch[1]))).toString();
            setPriority(val);
        }

        const uMatch = text.match(/\/u(\d+)/);
        if (uMatch) {
            const val = Math.min(10, Math.max(1, parseInt(uMatch[1]))).toString();
            if (val !== urgency()) {
                onUrgencySimpleChange(val);
            }
        }

        const tagRegex = /\/t\s*([^:/]+)(?=(?:[:/]))(?:[:](\d+))?/g;
        const newParsedTags: string[] = [];
        let match;
        while ((match = tagRegex.exec(text)) !== null) {
            const tagName = match[1].trim();
            if (tagName) {
                newParsedTags.push(tagName);
            }
        }

        const currentTags = [...tags()];
        const tagsToRemove = lastParsedTags.filter(t => !newParsedTags.includes(t));
        const tagsToAdd = newParsedTags.filter(t => !currentTags.includes(t));

        let nextTags = currentTags.filter(t => !tagsToRemove.includes(t));
        nextTags = [...nextTags, ...tagsToAdd];

        if (JSON.stringify(nextTags) !== JSON.stringify(currentTags)) {
            setTags(nextTags);
        }
        lastParsedTags = newParsedTags;
    });

    const onUrgencySimpleChange = (val: any) => {
        const value = typeof val === 'object' ? val.value : val;
        if (!value) return;

        setUrgency(value);
        const level = parseInt(value);
        if (!isNaN(level)) {
            const newDateIso = calculateDateFromUrgency(level);
            const dateObj = new Date(newDateIso);
            const localIso = new Date(dateObj.getTime() - (dateObj.getTimezoneOffset() * 60000)).toISOString().slice(0, 16);
            setDateString(localIso);
        }
    };

    const onDateInputChange = (e: Event) => {
        const val = (e.currentTarget as HTMLInputElement).value;
        setDateString(val);
        if (val) {
            const level = calculateUrgencyFromDate(new Date(val).toISOString());
            setUrgency(level.toString());
        }
    };

    const parseAndAdd = async () => {
        let text = input();
        if (!text || !priority() || !urgency()) {
            setShowValidation(true);
            toast.error("Please fill in all required fields (Title, Priority, Urgency)");
            if (!text) inputRef?.focus();
            return;
        }

        let finalPriority = parseInt(priority());
        let finalUrgency = parseInt(urgency());
        const finalTags = [...tags()];

        const pMatch = text.match(/\/p\s*(\d+)/);
        if (pMatch) {
            finalPriority = Math.min(10, Math.max(1, parseInt(pMatch[1])));
            text = text.replace(pMatch[0], "");
        }

        const uMatch = text.match(/\/u\s*(\d+)/);
        if (uMatch) {
            finalUrgency = Math.min(10, Math.max(1, parseInt(uMatch[1])));
            text = text.replace(uMatch[0], "");
        }

        const segments = text.split(/\/t\s*/);
        let title = segments[0];

        for (let i = 1; i < segments.length; i++) {
            const seg = segments[i];
            const firstColon = seg.indexOf(':');
            let tagName = "";
            let tagValue: number | undefined;
            let remainingText = "";

            if (firstColon === -1) {
                tagName = seg.trim();
            } else {
                tagName = seg.slice(0, firstColon).trim();
                const afterColon = seg.slice(firstColon + 1);
                const valueMatch = afterColon.match(/^\s*(\d+)/);

                if (valueMatch) {
                    tagValue = Math.min(10, Math.max(0, parseInt(valueMatch[1])));
                    remainingText = afterColon.slice(valueMatch[0].length);
                } else {
                    remainingText = afterColon;
                }
            }

            if (tagName) {
                if (!finalTags.includes(tagName)) {
                    finalTags.push(tagName);
                }
                if (tagValue !== undefined) {
                    await upsertTagDefinition(tagName, tagValue, undefined, resolvedTheme());
                }
            }
            title += " " + remainingText;
        }

        let finalDueDate: Date | null = null;
        if (dateString()) {
            finalDueDate = new Date(dateString());
        } else {
            const u = finalUrgency;
            const dateStr = calculateDateFromUrgency(u);
            finalDueDate = new Date(dateStr);
        }

        // Apply context tags at the time of creation
        const ctx = currentTaskContext();
        if (store.isNotepadMode) {
            const activeNoteId = (window as any)._activeNoteId;
            if (activeNoteId) {
                const note = store.notes.find(n => n.id === activeNoteId);
                if (note && note.title) {
                    const noteTagName = note.title.trim();
                    if (noteTagName && !finalTags.includes(noteTagName)) finalTags.push(noteTagName);
                }
            }
        } else if (typeof ctx === 'object') {
            if ('bucketId' in ctx) {
                const bucketName = ctx.name;
                if (bucketName) {
                    const tag = `@${bucketName}`;
                    if (!finalTags.includes(tag)) finalTags.push(tag);
                }
            } else if ('userId' in ctx) {
                const userName = ctx.name;
                if (userName) {
                    const tag = `@${userName}`;
                    if (!finalTags.includes(tag)) finalTags.push(tag);
                }
            }
        }

        addTask(title.replace(/\s+/g, " ").trim(), {
            priority: finalPriority,
            dueDate: finalDueDate || undefined,
            tags: finalTags,
            content: description(),
            size: parseInt(size())
        });

        resetQuickEntryState();

        const instance = editorInstance();
        if (instance) instance.commands.setContent("");

        if (props.onSuccess) props.onSuccess();
    };

    const applyTemplate = (template: TaskTemplate) => {
        setInput(template.title);
        setPriority(template.priority.toString());
        setUrgency(template.urgency.toString());
        setTags([...(template.tags || [])]);
        setDescription(template.content || "");

        const level = template.urgency;
        const newDateIso = calculateDateFromUrgency(level);
        const dateObj = new Date(newDateIso);
        const localIso = new Date(dateObj.getTime() - (dateObj.getTimezoneOffset() * 60000)).toISOString().slice(0, 16);
        setDateString(localIso);

        const instance = editorInstance();
        if (instance) {
            instance.commands.setContent(template.content || "");
        }
        toast.info(`Applied template: ${template.name}`);
    };

    return (
        <div class="flex flex-col h-full bg-card">
            <div class={cn("flex flex-col border-b border-border sticky top-0 bg-card z-10 transition-colors", showValidation() && !input() && "bg-destructive/5")}>
                <div class="flex items-center px-4 py-3">
                    <Search class={cn("text-muted-foreground mr-3 transition-colors", showValidation() && !input() && "text-destructive")} size={20} />
                    <TextField
                        class="flex-1"
                        validationState={showValidation() && !input() ? "invalid" : "valid"}
                    >
                        <TextFieldInput
                            id="quick-entry-input"
                            name="task-title"
                            ref={inputRef}
                            value={input()}
                            onInput={(e) => setInput(e.currentTarget.value)}
                            onKeyDown={(e) => e.key === "Enter" && parseAndAdd()}
                            placeholder="Task title... type /p1-10 for priority and /u1-10 for urgency"
                            class="border-none shadow-none focus-visible:ring-0 text-lg p-0"
                        />
                    </TextField>
                </div>
                <Show when={showValidation() && !input()}>
                    <div class="px-4 pb-2 -mt-1 flex items-center gap-1.5 animate-in fade-in slide-in-from-top-1 duration-200">
                        <div class="w-1.5 h-1.5 rounded-full bg-destructive" />
                        <span class="text-[0.625rem] font-bold uppercase tracking-widest text-destructive/80">
                            Title is required to create a task
                        </span>
                    </div>
                </Show>
            </div>

            <div class="flex-1 overflow-y-auto overscroll-contain">
                <div class="flex flex-col md:flex-row flex-wrap items-stretch md:items-center p-4 gap-4 border-b border-border bg-muted/10">
                    <div class="flex-1 min-w-0 md:min-w-[140px] space-y-1.5">
                        <label class="text-[0.625rem] font-bold uppercase tracking-wider text-muted-foreground ml-1">
                            Priority <span class="text-destructive">*</span>
                        </label>
                        <Select<any>
                            value={priority()}
                            onChange={(val) => {
                                const v = typeof val === 'object' ? val.value : val;
                                if (v) setPriority(v);
                            }}
                            options={PRIORITY_OPTIONS}
                            optionValue="value"
                            optionTextValue="label"
                            placeholder="Priority"
                            itemComponent={(props) => (
                                <SelectItem item={props.item}>
                                    {props.item.rawValue.label}
                                </SelectItem>
                            )}
                            validationState={showValidation() && !priority() ? "invalid" : "valid"}
                        >
                            <SelectTrigger
                                class={cn(
                                    "w-full bg-background border shadow-sm h-10 px-3 overflow-hidden transition-colors border-transparent",
                                    showValidation() && !priority() && "border-destructive/50 bg-destructive/5"
                                )}
                            >
                                <div class="flex items-center gap-2 truncate">
                                    <ArrowUpCircle size={14} class={cn("text-primary shrink-0", showValidation() && !priority() && "text-destructive")} />
                                    <span class={cn("text-sm font-medium truncate", showValidation() && !priority() && "text-destructive")}>
                                        {PRIORITY_OPTIONS.find(o => o.value === priority())?.label || (priority() === "" ? "Pick Priority" : priority())}
                                    </span>
                                </div>
                            </SelectTrigger>
                            <SelectContent />
                        </Select>
                    </div>

                    <div class="flex-1 min-w-0 md:min-w-[140px] space-y-1.5">
                        <label class="text-[0.625rem] font-bold uppercase tracking-wider text-muted-foreground ml-1">Size</label>
                        <Select<any>
                            value={size()}
                            onChange={(val) => {
                                const v = typeof val === 'object' ? val.value : val;
                                if (v) setSize(v);
                            }}
                            options={SIZE_OPTIONS}
                            optionValue="value"
                            optionTextValue="label"
                            placeholder="Size"
                            itemComponent={(props) => (
                                <SelectItem item={props.item}>
                                    {props.item.rawValue.label}
                                </SelectItem>
                            )}
                        >
                            <SelectTrigger class="w-full bg-background border-none shadow-sm h-10 px-3 overflow-hidden">
                                <div class="flex items-center gap-2 truncate">
                                    <Gauge size={14} class="text-primary shrink-0" />
                                    <span class="text-sm font-medium truncate">
                                        {SIZE_OPTIONS.find(o => o.value === size())?.label || size()}
                                    </span>
                                </div>
                            </SelectTrigger>
                            <SelectContent />
                        </Select>
                    </div>

                    <div class="flex-1 min-w-0 md:min-w-[140px] space-y-1.5">
                        <label class="text-[0.625rem] font-bold uppercase tracking-wider text-muted-foreground ml-1">
                            Urgency <span class="text-destructive">*</span>
                        </label>
                        <Select<any>
                            value={urgency()}
                            onChange={(val) => onUrgencySimpleChange(val)}
                            options={URGENCY_OPTIONS}
                            optionValue="value"
                            optionTextValue="label"
                            placeholder="Urgency"
                            itemComponent={(props) => (
                                <SelectItem item={props.item}>
                                    {props.item.rawValue.label}
                                </SelectItem>
                            )}
                            validationState={showValidation() && !urgency() ? "invalid" : "valid"}
                        >
                            <SelectTrigger
                                class={cn(
                                    "w-full bg-background border shadow-sm h-10 px-3 overflow-hidden transition-colors border-transparent",
                                    showValidation() && !urgency() && "border-destructive/50 bg-destructive/5"
                                )}
                            >
                                <div class="flex items-center gap-2 truncate">
                                    <Clock size={14} class={cn("text-primary shrink-0", showValidation() && !urgency() && "text-destructive")} />
                                    <span class={cn("text-sm font-medium truncate", showValidation() && !urgency() && "text-destructive")}>
                                        {URGENCY_OPTIONS.find(o => o.value === urgency())?.label || (urgency() === "" ? "Pick Urgency" : urgency())}
                                    </span>
                                </div>
                            </SelectTrigger>
                            <SelectContent />
                        </Select>
                    </div>
                </div>

                <div class="flex flex-col md:flex-row items-stretch md:items-center px-4 py-3 gap-4 bg-muted/10 border-b border-border">
                    <div class="flex-1 flex flex-wrap gap-2 items-center">
                        <TagPicker selectedTags={tags()} onTagsChange={setTags} />
                        <For each={tags().filter(t => !t.endsWith("_favorite__"))}>
                            {(tag) => (
                                <Badge
                                    variant="secondary"
                                    class="h-7 px-2 text-xs gap-1 bg-background border border-border/50 cursor-pointer hover:bg-destructive/10 hover:border-destructive/30 group/tag transition-all"
                                    style={{
                                        "background-color": (() => {
                                            const def = store.tagDefinitions.find(d => d.name === tag);
                                            const color = getThemeAdjustedColor(def?.color, def?.theme, resolvedTheme());
                                            return color ? `${color}15` : undefined;
                                        })(),
                                        "border-color": (() => {
                                            const def = store.tagDefinitions.find(d => d.name === tag);
                                            const color = getThemeAdjustedColor(def?.color, def?.theme, resolvedTheme());
                                            return color ? `${color}30` : undefined;
                                        })(),
                                        "color": (() => {
                                            const def = store.tagDefinitions.find(d => d.name === tag);
                                            return getThemeAdjustedColor(def?.color, def?.theme, resolvedTheme()) || "inherit";
                                        })()
                                    }}
                                    onClick={() => setTags(tags().filter(t => t !== tag))}
                                >
                                    <div
                                        class="w-1.5 h-1.5 rounded-full transition-colors group-hover/tag:bg-destructive"
                                        style={{
                                            "background-color": (store.tagDefinitions.find(d => d.name === tag)?.value ?? 5) > 5 ? "#22c55e" : (store.tagDefinitions.find(d => d.name === tag)?.value ?? 5) < 5 ? "#ef4444" : "#94a3b8"
                                        }}
                                    />
                                    {tag}
                                </Badge>
                            )}
                        </For>
                    </div>

                    <div class="w-full md:w-auto md:min-w-[200px] space-y-1.5">
                        <label class="text-[0.625rem] font-bold uppercase tracking-wider text-muted-foreground ml-1">Due Date</label>
                        <div class="relative">
                            <input
                                type="datetime-local"
                                value={dateString()}
                                onInput={onDateInputChange}
                                onClick={(e) => (e.target as HTMLInputElement).showPicker?.()}
                                onKeyDown={(e) => {
                                    if (e.key !== "Tab" && e.key !== "Escape") {
                                        e.preventDefault();
                                    }
                                }}
                                step="900"
                                class="w-full h-10 px-3 bg-background border-none rounded-md text-sm shadow-sm focus:outline-none focus:ring-1 focus:ring-ring relative cursor-pointer"
                            />
                        </div>
                    </div>
                </div>

                <div class="px-4 py-3 bg-card min-h-[80px]">
                    <Suspense fallback={<div class="h-20 animate-pulse bg-muted/20 rounded-lg" />}>
                        <TaskEditor
                            content={description()}
                            onUpdate={setDescription}
                            onEditorReady={setEditorInstance}
                            class="min-h-[60px] prose-sm"
                        />
                    </Suspense>
                </div>
            </div>

            <div class="p-4 bg-muted/30 flex justify-between items-center shrink-0 border-t border-border">
                <div class="flex items-center space-x-2 text-[0.625rem] font-bold text-muted-foreground uppercase tracking-widest">
                    <Command size={10} />
                    <span class="hidden sm:inline">K to focus • Enter to Add</span>
                    <span class="sm:hidden">Enter to Add</span>
                </div>

                <div class="flex items-center gap-2">
                    <Button
                        variant="ghost"
                        size="icon"
                        class="h-9 w-9 text-muted-foreground hover:text-destructive"
                        onClick={() => {
                            resetQuickEntryState();
                            editorInstance()?.commands.setContent("");
                        }}
                        title="Restart Quick Entry"
                    >
                        <RotateCcw size={16} />
                    </Button>
                    <Show when={(store.templates || []).length > 0}>
                        <Popover>
                            <PopoverTrigger
                                as={Button}
                                variant="ghost"
                                size="sm"
                                class="h-9 px-3 gap-2 hover:bg-primary/10 hover:text-primary text-muted-foreground transition-all rounded-xl border border-border/40"
                            >
                                <Copy size={14} />
                                <span class="text-[0.625rem] font-bold uppercase tracking-wider hidden sm:inline">Use Template</span>
                                <ChevronDown size={12} class="opacity-50" />
                            </PopoverTrigger>
                            <PopoverContent class="w-64 p-2 bg-card border-border shadow-xl">
                                <div class="space-y-1">
                                    <For each={store.templates}>
                                        {(template) => (
                                            <button
                                                class="w-full flex items-center gap-3 p-2 rounded-lg hover:bg-muted transition-colors text-left group"
                                                onClick={() => applyTemplate(template)}
                                            >
                                                <div class="w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center text-primary shrink-0 group-hover:bg-primary group-hover:text-primary-foreground transition-all">
                                                    <Copy size={14} />
                                                </div>
                                                <div class="min-w-0">
                                                    <p class="text-sm font-bold truncate tracking-tight">{template.name}</p>
                                                    <p class="text-[0.5625rem] uppercase font-black text-muted-foreground opacity-60 tracking-widest">
                                                        P:{template.priority} / U:{template.urgency}
                                                    </p>
                                                </div>
                                            </button>
                                        )}
                                    </For>
                                </div>
                            </PopoverContent>
                        </Popover>
                    </Show>

                    <Button size="sm" onClick={parseAndAdd}>
                        Create Task
                    </Button>
                </div>
            </div>
        </div>
    );
};
