import React, { useContext, useEffect, useState } from "react";
import { AuthContext } from "../../AuthProvider";
import { useNavigate, useParams } from "react-router-dom";
import "katex/dist/katex.min.css";
import "./MarkdownEditor.css";
import PathManager from "../PathManager";
import MarkdownView from "./MarkdownView";
import { useMarkdown, useSaveMarkdown } from "../../utils/queries/markdown-queries";
import {useMarkdownSetting, useUpdateMarkdownSetting} from "../../utils/queries/markdown-setting-queries";
import {useMarkdownTemplate, useMarkdownTemplates} from "../../utils/queries/markdown-template-queries";
import TemplatedEditor from "./TemplatedEditor";
import {useMarkdownTemplateSetting, useUpdateMarkdownTemplateSetting, useCreateMarkdownTemplateSetting} from "../../utils/queries/markdown-template-setting-queries";
import TemplateSelector from "../MarkdownTemplate/TemplateSelector";
import {useCreateMarkdownSetting} from "../../utils/queries/markdown-setting-queries";
import { Save, Code, LayoutTemplate } from "lucide-react";
import { Input, Textarea, Label } from "../ui/input";
import { Button } from "../ui/button";
import { Spinner } from "../ui/misc";

const MarkdownEditor = () => {
    const { roles } = useContext(AuthContext);
    const navigate = useNavigate();
    const { strId } = useParams();
    const id = Number(strId);
    const [title, setTitle] = useState("");
    const [content, setContent] = useState({});
    const [shortcut, setShortcut] = useState("");
    const [pathId, setPathId] = useState(1);
    const [isRawMode, setIsRawMode] = useState(false);
    const [rawContent, setRawContent] = useState("");
    const [jsonError, setJsonError] = useState("");
    const [selectedTemplate, setSelectedTemplate] = useState(null);
    const {data: markdown, isFetching: isMarkdownFetching, error} = useMarkdown(id);
    const saveMarkdown = useSaveMarkdown();
    const {data: setting, isFetching: isSettingFetching} = useMarkdownSetting(markdown?.setting_id);
    const {data: templateSetting, isFetching: isTemplateSettingFetching} = useMarkdownTemplateSetting(setting?.template_setting_id);
    const {data: template, isFetching: isTemplateFetching} = useMarkdownTemplate(templateSetting?.template_id);
    const updateTemplateSetting = useUpdateMarkdownTemplateSetting();
    const createTemplateSetting = useCreateMarkdownTemplateSetting();
    const updateSetting = useUpdateMarkdownSetting();
    const {data: templates, isFetching: templatesAreFetching} = useMarkdownTemplates();
    const createMarkdownSetting = useCreateMarkdownSetting();

    const notReady = isMarkdownFetching || isTemplateFetching || isSettingFetching || isTemplateSettingFetching || templatesAreFetching;

    useEffect(() => {
        if (markdown) {
            setTitle(markdown.title);
            if (markdown.isMessage) {
                navigate("/");
                alert(markdown.content || "Cannot edit this markdown");
                return;
            }
            try {
                const parsedContent = JSON.parse(markdown.content);
                setContent(parsedContent);
                setRawContent(JSON.stringify(parsedContent, null, 2));
                setShortcut(markdown.shortcut);
                setPathId(markdown.path_id);
            } catch (e) {
                console.error("Error parsing markdown content:", e);
                alert("Error parsing markdown content");
                navigate("/");
            }
        }
    }, [markdown, navigate]);

    useEffect(() => {
        if (template) {
            setSelectedTemplate(template);
        }
    }, [template]);

    const handleSave = () => {
        if (isRawMode && jsonError) {
            alert("Please fix the JSON errors before saving");
            return;
        }

        const saveData = {
            title,
            content: JSON.stringify(content),
            path_id: pathId,
            shortcut
        };
        console.log("markdown", markdown);
        console.log(markdown?.id ? "update" : "create",)
        if (!markdown?.id) {
            saveMarkdown.mutate(
                {data: saveData},
                {
                    onSuccess: (newMarkdown) => {
                        createMarkdownSetting.mutate({}, {
                            onSuccess: (settingRes) => {
                                saveMarkdown.mutate({
                                    id: newMarkdown.id,
                                    data: {
                                        setting_id: settingRes.id
                                    }
                                }, {
                                    onSuccess: () => {
                                        if (selectedTemplate?.id) {
                                            createTemplateSetting.mutate({
                                                template_id: selectedTemplate.id
                                            }, {
                                                onSuccess: (templateSettingRes) => {
                                                    updateSetting.mutate({
                                                        id: settingRes.id,
                                                        data: {
                                                            template_setting_id: templateSettingRes.id
                                                        }
                                                    }, {
                                                        onSuccess: () => {
                                                            navigate("/");
                                                        }
                                                    });
                                                }
                                            });
                                        } else {
                                            navigate("/");
                                        }
                                    }
                                });
                            }
                        });
                    },
                    onError: () => {
                        alert("Error saving markdown file");
                    }
                }
            );
        } else {
            console.log("try update");
            saveMarkdown.mutate(
                {id, data: saveData},
                {
                    onSuccess: () => {
                        navigate("/markdown/" + id);
                    },
                    onError: () => {
                        alert("Error saving markdown file");
                    }
                }
            );
        }
    };

    const toggleEditMode = () => {
        if (isRawMode) {
            try {
                const parsed = JSON.parse(rawContent);
                setContent(parsed);
                setJsonError("");
                setIsRawMode(false);
            } catch (e) {
                setJsonError("Invalid JSON: " + e.message);
                return;
            }
        } else {
            setRawContent(JSON.stringify(content, null, 2));
            setIsRawMode(true);
        }
    };

    const handleRawContentChange = (e) => {
        const newRawContent = e.target.value;
        setRawContent(newRawContent);
        try {
            const parsed = JSON.parse(newRawContent);
            setContent(parsed);
            setJsonError("");
        } catch (e) {
            setJsonError("Invalid JSON: " + e.message);
        }
    };

    const handleTemplateChange = (newTemplate) => {
        setSelectedTemplate(newTemplate);
        if (templateSetting) {
            updateTemplateSetting.mutate({
                id: templateSetting.id,
                data: {
                    template_id: newTemplate.id
                }
            });
        }
    };

    const hasPermission = roles.includes("admin") || roles.includes("creator");
    if (!hasPermission)
        return (
            <div className="rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3 font-mono text-sm text-destructive">
                Permission Denied
            </div>
        );

    if(notReady) {
        console.log("=============");
        console.log("isMarkdownFetching", isMarkdownFetching );
        console.log("isTemplateFetching", isTemplateFetching );
        console.log("isSettingFetching", isSettingFetching );
        console.log("isTemplateSettingFetching", isTemplateSettingFetching);
        console.log( "TemplatesAreFetching", templatesAreFetching);
        console.log("----------------");
        return (
            <div className="flex justify-center py-20">
                <Spinner label="Loading editor" />
            </div>
        );
    }

    if(error)
        return (
            <div className="rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3 font-mono text-sm text-destructive">
                {error.message || "Failed to load markdown"}
            </div>
        );
    return (
        <div className="markdown-editor-container mx-auto max-w-[90vw] px-6 py-8">
            <h2 className="mb-6 font-mono text-2xl font-bold tracking-tight text-foreground">
                {id ? "Edit Markdown" : "Create Markdown"}
            </h2>
            <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
                <div>
                    <form className="space-y-5">
                        <div className="space-y-2">
                            <Label htmlFor="md-title">Title</Label>
                            <Input
                                id="md-title"
                                type="text"
                                placeholder="Enter title"
                                value={title}
                                onChange={(e) => setTitle(e.target.value)}
                            />
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="md-shortcut">Shortcut</Label>
                            <Input
                                id="md-shortcut"
                                type="text"
                                placeholder="Enter shortcut"
                                value={shortcut}
                                onChange={(e) => setShortcut(e.target.value)}
                            />
                        </div>
                        <div className="space-y-2">
                            <Label>Path</Label>
                            <PathManager
                                currentPathId={pathId}
                                onPathChange={setPathId}
                            />
                        </div>

                        <div>
                            <TemplateSelector
                                template={selectedTemplate || template}
                                onChange={handleTemplateChange}
                            />
                        </div>

                        <div className="space-y-2">
                            <div className="flex items-center justify-between">
                                <Label>Content</Label>
                                <Button
                                    type="button"
                                    variant="outline"
                                    size="sm"
                                    onClick={toggleEditMode}
                                >
                                    {isRawMode ? (
                                        <>
                                            <LayoutTemplate className="h-4 w-4" /> Switch to Template Editor
                                        </>
                                    ) : (
                                        <>
                                            <Code className="h-4 w-4" /> Switch to Raw Editor
                                        </>
                                    )}
                                </Button>
                            </div>
                            {isRawMode ? (
                                <div className="space-y-2">
                                    <p className="text-xs text-muted-foreground">
                                        Edit the JSON directly. Make sure it's valid JSON before saving.
                                    </p>
                                    <Textarea
                                        className={`raw-editor h-[70vh] font-mono text-sm ${jsonError ? "border-destructive focus-visible:border-destructive" : ""}`}
                                        value={rawContent}
                                        onChange={handleRawContentChange}
                                        placeholder="Enter JSON content here"
                                    />
                                    {jsonError && (
                                        <p className="font-mono text-xs text-destructive">{jsonError}</p>
                                    )}
                                </div>
                            ) : (
                                <TemplatedEditor
                                    style={{height: "40vh"}}
                                    content={content}
                                    template={!markdown?.id ? selectedTemplate : template}
                                    onContentChanged={(k, v) => setContent(
                                        prev => ({...prev, [k]: v})
                                    )}
                                />
                            )}
                        </div>

                        <div>
                            <Button
                                type="button"
                                onClick={handleSave}
                                disabled={saveMarkdown.isLoading}
                            >
                                <Save className="h-4 w-4" />
                                {saveMarkdown.isLoading ? "Saving..." : "Save"}
                            </Button>
                        </div>
                    </form>
                </div>

                <div>
                    <h3 className="mb-3 font-mono text-sm font-semibold uppercase tracking-wide text-foreground">
                        Preview
                    </h3>
                    <MarkdownView
                        content={content}
                        template={!markdown?.id ? selectedTemplate : template}
                        height='70vh'
                    />
                </div>
            </div>
        </div>
    );
};

export default MarkdownEditor;
