"use client";

import { useEditor, EditorContent, ReactNodeViewRenderer } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { useEffect, useState, useRef } from "react";
import { AIAssist } from "./ai-assist";
import { Sparkles } from "lucide-react";
import { Toolbar } from "./editor/toolbar";
import { SlashCommand, getSuggestionItems, renderSuggestionItems } from "./editor/slash-command";
import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
import { lowlight } from 'lowlight';
import { CodeBlockComponent } from "./editor/code-block";
import Link from "@tiptap/extension-link";

import Underline from "@tiptap/extension-underline";
import Subscript from "@tiptap/extension-subscript";
import Superscript from "@tiptap/extension-superscript";
import Highlight from "@tiptap/extension-highlight";
import TaskList from "@tiptap/extension-task-list";
import TaskItem from "@tiptap/extension-task-item";
import { Callout } from "./editor/extensions/callout";
import { AIMark } from "./editor/extensions/ai-mark";
import { TaskItemComponent } from "./editor/extensions/task-item";
import { useSettingsStore } from "@/lib/settings-store";
import { Table } from "@tiptap/extension-table";
import TableRow from "@tiptap/extension-table-row";
import TableCell from "@tiptap/extension-table-cell";
import TableHeader from "@tiptap/extension-table-header";
import Image from "@tiptap/extension-image";
import Youtube from "@tiptap/extension-youtube";
import TextAlign from "@tiptap/extension-text-align";
import Gapcursor from "@tiptap/extension-gapcursor";
import { Markdown } from 'tiptap-markdown';

interface EditorProps {
    content: string;
    onChange: (content: string) => void;
    onEditorReady?: (editor: any) => void;
    onToggleAI?: () => void;
    onExport?: () => void;
    editable?: boolean;
}

export function Editor({ content, onChange, onEditorReady, onToggleAI, onExport, editable = true }: EditorProps) {
    const [showAI, setShowAI] = useState(false);
    const [isGenerating, setIsGenerating] = useState(false);
    const abortControllerRef = useRef<AbortController | null>(null);
    const { fontFamily, fontSize } = useSettingsStore();

    const editor = useEditor({
        extensions: [
            Gapcursor,
            StarterKit.configure({
                heading: {
                    levels: [1, 2, 3],
                },
                codeBlock: false,
                bulletList: {
                    keepMarks: true,
                    keepAttributes: false,
                },
                orderedList: {
                    keepMarks: true,
                    keepAttributes: false,
                },
            }),
            SlashCommand.configure({
                suggestion: {
                    items: getSuggestionItems,
                    render: renderSuggestionItems,
                },
            }),
            CodeBlockLowlight
                .extend({
                    addNodeView() {
                        return ReactNodeViewRenderer(CodeBlockComponent)
                    }
                })
                .configure({ lowlight, defaultLanguage: 'plaintext' }),
            Link.configure({
                openOnClick: false,
                HTMLAttributes: {
                    class: 'cursor-pointer text-blue-600 dark:text-blue-400 hover:underline hover:text-blue-800 dark:hover:text-blue-300 transition-colors',
                },
            }),
            Underline,
            Subscript,
            Superscript,
            Highlight.configure({
                multicolor: true,
            }),
            TaskList,
            TaskItem.configure({
                nested: true,
            }).extend({
                addNodeView() {
                    return ReactNodeViewRenderer(TaskItemComponent)
                }
            }),
            Callout,
            AIMark,
            Table.configure({
                resizable: true,
            }),
            TableRow,
            TableHeader,
            TableCell,
            Image.configure({
                inline: true,
                allowBase64: true,
            }),
            Youtube.configure({
                controls: false,
            }),
            TextAlign.configure({
                types: ['heading', 'paragraph'],
            }),
            Markdown.configure({
                html: true,                  // Allow HTML input/output
                transformPastedText: true,   // Auto-transform pasted markdown
                transformCopiedText: true,   // Auto-transform copied markdown
            })
        ],
        content: content,
        onUpdate: ({ editor }) => {
            if (editor.getHTML() !== content) {
                onChange(editor.getHTML());
            }
        },
        editorProps: {
            attributes: {
                class: "prose prose-zinc dark:prose-invert max-w-none focus:outline-none min-h-[300px]",
                style: `font-family: ${fontFamily}; font-size: ${fontSize}px; --editor-line-height: ${useSettingsStore.getState().lineHeight}; --table-line-height: ${useSettingsStore.getState().tableLineHeight};`,
                spellcheck: "false",
            },
        },
        editable: editable,
        immediatelyRender: false,
    });

    useEffect(() => {
        if (editor) {
            editor.setEditable(editable);
        }
    }, [editor, editable]);

    useEffect(() => {
        if (editor && content !== editor.getHTML()) {
            queueMicrotask(() => {
                editor.commands.setContent(content);
            });
        }
        if (editor && onEditorReady) {
            onEditorReady(editor);
        }
    }, [content, editor, onEditorReady]);

    const handleStopAI = () => {
        if (abortControllerRef.current) {
            abortControllerRef.current.abort();
            abortControllerRef.current = null;
        }
        setIsGenerating(false);
    };

    const handleAISuggest = async (prompt: any) => {
        if (!editor) return;

        const { aiConfig } = useSettingsStore.getState();
        if (!aiConfig.apiKey) {
            alert("请先在设置中配置 AI API Key");
            return;
        }

        const { from, to } = editor.state.selection;
        const selectedText = editor.state.doc.textBetween(from, to, " ");

        // Custom prompt logic
        const systemPrompt = prompt.systemPrompt || "You are a helpful assistant.";
        let userPrompt = selectedText;

        if (!userPrompt) {
            const pos = from;
            userPrompt = editor.state.doc.textBetween(Math.max(0, pos - 1000), pos, "\n");
        }

        setShowAI(false);
        setIsGenerating(true);
        abortControllerRef.current = new AbortController();

        try {
            const response = await fetch("/api/ai/chat", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    config: aiConfig,
                    messages: [
                        { role: "system", content: systemPrompt },
                        { role: "user", content: userPrompt }
                    ]
                }),
                signal: abortControllerRef.current.signal
            });

            if (!response.ok || !response.body) {
                throw new Error(await response.text());
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();

            editor.chain().focus().insertContent("\n\n").toggleMark('aiMark').run();

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                const chunk = decoder.decode(value);
                const lines = chunk.split('\n');
                for (const line of lines) {
                    if (line.startsWith('data: ') && line !== 'data: [DONE]') {
                        try {
                            const data = JSON.parse(line.slice(6));
                            const content = data.choices[0]?.delta?.content;
                            if (content) {
                                editor.commands.insertContent(content);
                            }
                        } catch (e) {
                            // ignore
                        }
                    }
                }
            }
            editor.chain().focus().insertContent("\n\n").unsetMark('aiMark').run();

        } catch (e: any) {
            if (e.name === 'AbortError') {
                editor.chain().focus().insertContent(" [已停止]").unsetMark('aiMark').run();
            } else {
                console.error("AI Error", e);
                alert("AI 请求失败，请检查配置或网络");
            }
        } finally {
            setIsGenerating(false);
            abortControllerRef.current = null;
        }
    };

    if (!editor) return null;

    return (
        <div className="relative group/editor flex flex-col min-h-full">
            <Toolbar editor={editor} onToggleAI={onToggleAI} onExport={onExport} />

            {showAI && (
                <div className="absolute top-12 right-4 z-50">
                    <AIAssist
                        isOpen={showAI}
                        onSuggest={handleAISuggest}
                        onClose={() => setShowAI(false)}
                    />
                </div>
            )}

            <div className="flex-1 mt-4">
                <EditorContent editor={editor} />
            </div>

            <button
                onClick={(e) => {
                    e.preventDefault();
                    if (isGenerating) {
                        handleStopAI();
                    } else {
                        setShowAI(!showAI);
                    }
                }}
                className={`fixed bottom-8 right-8 p-3 rounded-full shadow-lg hover:scale-110 transition-transform z-40 ${isGenerating
                    ? "bg-red-500 text-white animate-pulse"
                    : "bg-primary text-primary-foreground"
                    }`}
                title={isGenerating ? "停止生成 (Stop)" : "AI 助手 (AI Assist)"}
            >
                {isGenerating ? <div className="h-5 w-5 bg-current rounded-sm" /> : <Sparkles size={20} />}
            </button>


        </div>
    );
}
