import { type Component, createSignal, createMemo, For, Show } from "solid-js";
import { store, renameTagDefinition } from "@/store";
import { pb } from "@/lib/pocketbase";
import { type Note } from "@/store";
import { Trash2, Lock, Unlock, Search, Link, X, ChevronRight } from "lucide-solid";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { TaskEditor } from "@/components/TaskEditor";
import { NOTES_COLLECTION } from "@/lib/constants";
import { TaskCard } from "@/components/TaskCard";
import { NotesSidebar } from "@/components/NotesSidebar";

export const NotepadView: Component<{
    selectedNoteId: string | null;
    setSelectedNoteId: (id: string | null) => void;
    hideNavigation?: boolean;
}> = (props) => {
    const [isLinking, setIsLinking] = createSignal(false);
    const [linkSearchQuery, setLinkSearchQuery] = createSignal("");
    const [isLinkedTasksOpen, setIsLinkedTasksOpen] = createSignal(true);

    const currentUserId = pb.authStore.model?.id;

    // Derived states
    const activeNote = createMemo(() => {
        const id = props.selectedNoteId?.trim();
        return store.notes.find(n => n.id === id) || null;
    });

    const handleUpdateNote = async (id: string, data: Partial<Note>) => {
        try {
            await pb.collection(NOTES_COLLECTION).update(id, data);
        } catch (e: any) {
            if (!e.isAbort) {
                console.error("Failed to update note", e);
            }
        }
    };

    let contentUpdateTimeout: number | undefined;
    const handleUpdateContent = (id: string, html: string) => {
        clearTimeout(contentUpdateTimeout);
        contentUpdateTimeout = window.setTimeout(async () => {
            try {
                await pb.collection(NOTES_COLLECTION).update(id, { content: html });
            } catch (e: any) {
                if (!e.isAbort) {
                    console.error("Failed to update note content", e);
                }
            }
        }, 500);
    };

    const handleRenameNote = async (id: string, oldTitle: string, newTitle: string) => {
        // 1. Update the note title
        await handleUpdateNote(id, { title: newTitle });

        // 2. Rename the TagDefinition (preserves color) and propagate to all tagged tasks
        // Use '#' prefix for note tags
        await renameTagDefinition(`#${oldTitle}`, `#${newTitle}`);
    };
    const handleDeleteNote = async (id: string) => {
        try {
            await pb.collection(NOTES_COLLECTION).delete(id);
            if (props.selectedNoteId === id) {
                props.setSelectedNoteId(null);
            }
        } catch (e) {
            console.error("Failed to delete note", e);
        }
    };

    const handleLinkTask = async (taskId: string) => {
        const note = activeNote();
        if (!note) return;
        const newTasks = [...(note.tasks || []), taskId];
        await handleUpdateNote(note.id, { tasks: newTasks });
        setIsLinking(false);
        setLinkSearchQuery("");
    };

    const handleUnlinkTask = async (taskId: string) => {
        const note = activeNote();
        if (!note) return;
        const newTasks = (note.tasks || []).filter(id => id !== taskId);
        await handleUpdateNote(note.id, { tasks: newTasks });
    };

    // Linked tasks calculation
    const linkedTasks = createMemo(() => {
        const note = activeNote();
        if (!note) return [];
        const noteTagName = `#${note.title}`;
        return store.tasks.filter(t => {
            // Explicit relation
            if (note.tasks && note.tasks.includes(t.id)) return true;
            // Tag relation (case-insensitive title match with # prefix)
            if (t.tags && t.tags.some(tag => tag.toLowerCase() === noteTagName.toLowerCase())) return true;
            return false;
        });
    });

    const unlinkedTasks = createMemo(() => {
        const note = activeNote();
        if (!note) return [];
        const q = linkSearchQuery().toLowerCase();

        // Get names of pinned/subscribed buckets
        const pinnedBucketNames = store.buckets
            .filter(b => store.subscribedBuckets.includes(b.id))
            .map(b => b.name.toLowerCase());

        const allBucketNames = store.buckets.map(b => b.name.toLowerCase());

        return store.tasks.filter(t => {
            if (t.deletedAt) return false; // Don't show trashed tasks

            // Filter out tasks from unpinned buckets
            const taskBucketTags = (t.tags || []).filter(tag => allBucketNames.includes(tag.toLowerCase()));
            if (taskBucketTags.length > 0) {
                // If it belongs to a bucket, at least one must be pinned
                const hasPinnedBucket = taskBucketTags.some(tag => pinnedBucketNames.includes(tag.toLowerCase()));
                if (!hasPinnedBucket) return false;
            }

            if (note.tasks && note.tasks.includes(t.id)) return false; // Already linked
            if (!q) return false; // Don't show all by default
            return t.title.toLowerCase().includes(q);
        }).slice(0, 10);
    });

    const openQuickEntry = () => {
        window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 'k' }));
    };

    return (
        <div class="flex flex-col md:flex-row h-full bg-background md:bg-card md:border md:border-border md:rounded-xl md:shadow-sm overflow-hidden relative">
            {/* Mobile Notes List */}
            <Show when={!props.hideNavigation}>
                <div class={cn(
                    "md:hidden absolute inset-0 z-10 bg-card overflow-hidden flex flex-col h-full transition-all duration-200 ease-out",
                    props.selectedNoteId ? "opacity-0 pointer-events-none -translate-x-8" : "opacity-100 translate-x-0"
                )}>
                    <NotesSidebar selectedNoteId={props.selectedNoteId} setSelectedNoteId={props.setSelectedNoteId} />
                </div>
            </Show>

            {/* Note Editor (Main Panel) */}
            <div class={cn(
                "flex-1 bg-card min-w-0 transition-all duration-200 ease-out h-full overflow-y-auto md:overflow-hidden absolute md:relative inset-0 z-20 md:z-0",
                !props.selectedNoteId ? "opacity-0 pointer-events-none md:pointer-events-auto md:opacity-100 translate-x-8 md:translate-x-0 md:flex items-center justify-center bg-muted/5" : "opacity-100 translate-x-0 flex flex-col md:flex-row"
            )}>
                <Show when={activeNote()} fallback={
                    <div class="text-center space-y-6 opacity-40 select-none flex flex-col items-center justify-center h-full">
                        <div class="h-16 w-16 rounded-3xl bg-muted flex items-center justify-center mb-2 animate-pulse">
                            <Search size={32} class="text-muted-foreground/50" />
                        </div>
                        <Show when={props.selectedNoteId && store.notes.length === 0} fallback={
                            <div class="space-y-2">
                                <p class="text-sm font-bold tracking-widest uppercase">No Note Selected</p>
                                <p class="text-[0.8rem] text-muted-foreground max-w-[200px] leading-relaxed">
                                    Select an existing note from the sidebar or create a new one to get started.
                                </p>
                            </div>
                        }>
                            <p class="text-sm font-medium tracking-wide italic">Loading note...</p>
                        </Show>
                    </div>
                }>
                    {(note) => {
                        const isOwner = note().user === currentUserId;
                        const canEdit = isOwner || !note().isPrivate;

                        return (
                            <>
                                {/* Editor Area */}
                                <div class="flex-1 flex flex-col min-w-0 md:h-full overflow-visible md:overflow-y-auto relative p-4 md:p-6 space-y-4 md:space-y-6 scroll-smooth">
                                    <div class="space-y-4">
                                        <div class="flex items-start justify-between gap-4">
                                            <input
                                                class="text-3xl sm:text-4xl font-black tracking-tight bg-transparent border-none outline-none focus:ring-0 flex-1 placeholder:text-muted-foreground/30 px-0 min-w-0"
                                                value={note().title}
                                                placeholder="Note Title"
                                                readOnly={!canEdit}
                                                onBlur={(e) => {
                                                    const val = e.currentTarget.value.trim() || 'Untitled';
                                                    if (val !== note().title) handleRenameNote(note().id, note().title, val);
                                                }}
                                            />
                                            <div class="flex items-center gap-2 shrink-0 pt-1">
                                                <Show when={isOwner}>
                                                    <Button
                                                        variant="ghost"
                                                        size="sm"
                                                        class={cn("h-8 text-[0.625rem] font-bold uppercase tracking-widest", note().isPrivate ? "text-orange-500 hover:bg-orange-500/10" : "text-muted-foreground")}
                                                        onClick={() => handleUpdateNote(note().id, { isPrivate: !note().isPrivate })}
                                                    >
                                                        <Show when={note().isPrivate} fallback={<><Unlock size={12} class="mr-1.5" /> Public</>}>
                                                            <><Lock size={12} class="mr-1.5" /> Private</>
                                                        </Show>
                                                    </Button>
                                                </Show>

                                                <Show when={isOwner}>
                                                    <Button
                                                        variant="ghost"
                                                        size="icon"
                                                        class="h-8 w-8 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg"
                                                        onClick={() => handleDeleteNote(note().id)}
                                                    >
                                                        <Trash2 size={16} />
                                                    </Button>
                                                </Show>
                                            </div>
                                        </div>

                                    </div>

                                    {/* Editor Instance */}
                                    <div class="flex-1 min-h-[300px] border border-border/50 rounded-xl p-4 bg-background shadow-sm mb-4">
                                        <TaskEditor
                                            content={note().content}
                                            onUpdate={(html) => handleUpdateContent(note().id, html)}
                                            editable={canEdit}
                                        />
                                    </div>
                                </div>

                                {/* Linked Tasks Sidebar */}
                                <div class={cn(
                                    "border-t md:border-t-0 md:border-l border-border bg-muted/5 flex flex-col shrink-0 transition-all duration-300 ease-in-out overflow-hidden",
                                    isLinkedTasksOpen() ? "w-full md:w-80 lg:w-96 h-auto md:h-full" : "w-full md:w-12 h-12 md:h-full cursor-pointer hover:bg-muted/10"
                                )}
                                    onClick={() => {
                                        if (!isLinkedTasksOpen()) {
                                            setIsLinkedTasksOpen(true);
                                        }
                                    }}>
                                    <div class={cn("p-4 border-b border-border bg-card/50 flex flex-col gap-3", !isLinkedTasksOpen() && "items-center justify-center p-0 h-full md:py-4")}>
                                        <div
                                            class="flex items-center justify-between cursor-pointer group"
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setIsLinkedTasksOpen(!isLinkedTasksOpen());
                                            }}
                                        >
                                            <div class={cn("flex items-center gap-2", !isLinkedTasksOpen() && "md:flex-col")}>
                                                <ChevronRight size={14} class={cn("text-muted-foreground transition-all duration-300 group-hover:text-foreground", !isLinkedTasksOpen() ? "rotate-90 md:rotate-0" : "rotate-90 md:rotate-180")} />
                                                <Show when={isLinkedTasksOpen()} fallback={
                                                    <div class="hidden md:flex items-center justify-center -rotate-90 origin-center whitespace-nowrap mt-8 text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground/50">
                                                        <Link size={10} class="mr-2 rotate-90" />
                                                        Linked Tasks
                                                    </div>
                                                }>
                                                    <h3 class="text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-2">
                                                        <Link size={12} />
                                                        Linked Tasks
                                                    </h3>
                                                </Show>
                                                <Show when={!isLinkedTasksOpen()}>
                                                    <div class="md:hidden flex items-center justify-center text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground">
                                                        <Link size={12} class="mr-2" />
                                                        Linked Tasks
                                                    </div>
                                                </Show>
                                            </div>
                                            <Show when={isLinkedTasksOpen()}>
                                                <div class="flex items-center gap-1">
                                                    <Button
                                                        size="icon"
                                                        variant="ghost"
                                                        class="h-7 w-7 rounded-lg text-muted-foreground hover:text-primary hover:bg-primary/10"
                                                        onClick={(e) => {
                                                            e.stopPropagation();
                                                            setIsLinking(!isLinking());
                                                        }}
                                                        title="Link Existing Task"
                                                    >
                                                        <Link size={14} />
                                                    </Button>
                                                    <Button
                                                        size="sm"
                                                        variant="ghost"
                                                        class="h-7 px-2 text-[0.625rem] font-bold uppercase tracking-wider text-primary hover:bg-primary/10 rounded-lg"
                                                        onClick={(e) => {
                                                            e.stopPropagation();
                                                            openQuickEntry();
                                                        }}
                                                        title="Create Task via Quick Entry"
                                                    >
                                                        + Task
                                                    </Button>
                                                </div>
                                            </Show>
                                        </div>

                                        <Show when={isLinkedTasksOpen() && isLinking()}>
                                            <div class="animate-in fade-in slide-in-from-top-2 space-y-2">
                                                <div class="relative">
                                                    <Search size={14} class="absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground/50" />
                                                    <input
                                                        type="text"
                                                        placeholder="Search tasks to link..."
                                                        value={linkSearchQuery()}
                                                        onInput={(e) => setLinkSearchQuery(e.currentTarget.value)}
                                                        class="w-full bg-background border border-border/50 rounded-lg pl-8 pr-3 py-1.5 text-xs outline-none focus:ring-1 focus:ring-primary/30 shadow-sm"
                                                    />
                                                </div>
                                                <Show when={linkSearchQuery() && unlinkedTasks().length > 0}>
                                                    <div class="bg-background border border-border rounded-lg shadow-xl overflow-hidden max-h-48 overflow-y-auto">
                                                        <For each={unlinkedTasks()}>
                                                            {(t) => (
                                                                <button
                                                                    class="w-full text-left p-2 text-xs hover:bg-muted border-b border-border last:border-0 truncate"
                                                                    onClick={() => handleLinkTask(t.id)}
                                                                >
                                                                    {t.title}
                                                                </button>
                                                            )}
                                                        </For>
                                                    </div>
                                                </Show>
                                            </div>
                                        </Show>
                                    </div>
                                    <Show when={isLinkedTasksOpen()}>
                                        <div class="flex-1 overflow-y-auto p-4 space-y-4">
                                            <For each={linkedTasks()} fallback={
                                                <div class="text-center text-xs text-muted-foreground p-6 bg-muted/10 border border-dashed border-border/50 rounded-xl flex flex-col items-center gap-2">
                                                    <Link size={24} class="opacity-20" />
                                                    <p>No tasks linked yet.</p>
                                                    <p class="text-[0.6rem] opacity-70 max-w-[200px]">Link an existing task, create a new one, or add the tag #{note().title} to a task.</p>
                                                </div>
                                            }>
                                                {(task) => (
                                                    <div class="relative group">
                                                        <TaskCard task={task} />
                                                        {/* If explicitly linked, allow unlinking. If linked by tag, they should remove the tag from the task, which we can't easily do here unless we implement it. */}
                                                        <Show when={note().tasks && note().tasks.includes(task.id)}>
                                                            <button
                                                                class="absolute -top-2 -right-2 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity shadow-sm hover:scale-110"
                                                                onClick={(e) => {
                                                                    e.stopPropagation();
                                                                    handleUnlinkTask(task.id);
                                                                }}
                                                                title="Unlink Task"
                                                            >
                                                                <X size={12} />
                                                            </button>
                                                        </Show>
                                                    </div>
                                                )}
                                            </For>
                                        </div>
                                    </Show>
                                </div>
                                <Show when={!props.hideNavigation}>
                                    {/* Sticky Full-Width Mobile Close Footer */}
                                    <div class="md:hidden sticky bottom-0 z-[60] p-4 bg-background/95 backdrop-blur-sm border-t border-border flex justify-end shrink-0 w-full shadow-[0_-10px_40px_-5px_hsl(var(--background))]">
                                        <Button
                                            variant="secondary"
                                            class="w-full h-11 rounded-xl text-sm font-bold shadow-sm"
                                            onClick={() => props.setSelectedNoteId(null)}
                                        >
                                            <X size={16} class="mr-2" />
                                            Close Note
                                        </Button>
                                    </div>
                                </Show>
                            </>
                        );
                    }}
                </Show >
            </div>
        </div >
    );
};
