"use client";

import Breadcrumbs from "@/components/user/components/Breadcrumbs";
import { useTranslation } from "@/hooks/useTranslation";
import { createChapter } from "@/libs/axios/modules/chapter";
import { getMyPostDetail } from "@/libs/axios/modules/post";
import { PostModel } from "@/models";
import BlockquoteExtension from "@tiptap/extension-blockquote";
import BoldExtension from "@tiptap/extension-bold";
import DocumentExtension from "@tiptap/extension-document";
import HistoryExtension from "@tiptap/extension-history";
import ItalicExtension from "@tiptap/extension-italic";
import ParagraphExtension from "@tiptap/extension-paragraph";
import TextExtension from "@tiptap/extension-text";
import UnderlineExtension from "@tiptap/extension-underline";
import { EditorContent, useEditor } from "@tiptap/react";
import { format } from "date-fns";
import { AnimatePresence, motion } from "framer-motion";
import { Bold, Calendar, ChevronDown, Eye, Italic, Quote, Redo2, Send, Underline, Undo2, X } from "lucide-react";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "react-toastify";

function wordLength(val: string): number {
    if (!val) return 0;

    const cleanText = val
        .replace(/<\/?strong>/g, "")
        .replace(/<\/?em>/g, "")
        .replace(/<\/?b>/g, "")
        .replace(/<\/?i>/g, "")
        .replace(/<\/?u>/g, "")
        .replace(/<\/?blockquote>/g, "")
        .replace(/<[^>]+>/g, " ")
        .replace(/&nbsp;/gi, " ")
        .replace(/&amp;/gi, "&")
        .replace(/&lt;/gi, "<")
        .replace(/&gt;/gi, ">")
        .replace(/(\r\n|\n|\r)/gm, " ")
        .replace(/\s+/g, " ")
        .trim();

    const matches = cleanText.match(/\b[\wÀ-ÿ]+(?:[-'][\wÀ-ÿ]+)*\b/g);
    return matches ? matches.length : 0;
}

function wordCount(html: string) {
    const cleanContent = html
        .replace(/&nbsp;/gi, " ")
        .replace(/<p[^>]*>/gi, "<div>")
        .replace(/<\/p>/gi, "</div>")
        .replace(/<(?!\/?(div|b|i|u|blockquote)\b)[^>]*>/gi, "");
    console.log(html, cleanContent)
    return wordLength(cleanContent);
}

function wordCountColor(count: number) {
    if (count < 800) return "text-amber-500 bg-amber-50";
    if (count <= 1200) return "text-green-600 bg-green-50";
    return "text-red-500 bg-red-50";
}

function PreviewModal({
    open, title, novelTitle, content, onClose,
}: {
    open: boolean;
    title: string;
    novelTitle: string;
    content: string;
    onClose: () => void;
}) {
    useEffect(() => {
        document.body.style.overflow = open ? "hidden" : "";
        return () => { document.body.style.overflow = ""; };
    }, [open]);

    if (!open) return null;
    return (
        <AnimatePresence>
            {open && (
                <>
                    <motion.div
                        className="fixed inset-0 z-9999 bg-black/40 backdrop-blur-sm"
                        onClick={onClose}
                        initial={{ opacity: 0 }}
                        animate={{ opacity: 1 }}
                        exit={{ opacity: 0 }}
                        transition={{ duration: 0.2 }}
                    />

                    <div className="fixed inset-0 z-10000 flex flex-col justify-center items-center">
                        <motion.div
                            className="flex flex-col bg-slate-50 w-full h-full md:rounded-2xl md:max-w-2xl md:max-h-[90vh] md:m-auto md:shadow-xl overflow-hidden"
                            initial={{ y: "100%" }}
                            animate={{ y: 0 }}
                            exit={{ y: "100%" }}
                            transition={{ type: "spring", stiffness: 300, damping: 30 }}
                        >
                            <div className="flex items-center px-6 py-4 bg-slate-50 shrink-0">
                                <p className="flex-1 text-lg font-semibold text-slate-800 capitalize">Preview</p>
                                <button
                                    onClick={onClose}
                                    className="p-2 hover:bg-slate-200 rounded-xl transition-colors cursor-pointer"
                                >
                                    <X className="w-5 h-5 text-slate-800" />
                                </button>
                            </div>

                            <div className="flex-1 overflow-y-auto">
                                <div className="px-6 pt-2 pb-3 flex flex-col gap-1">
                                    <div className="flex flex-col gap-0.5">
                                        <h1 className="text-3xl font-bold text-slate-800 capitalize">Bab 1</h1>
                                        <h2 className="text-3xl font-bold text-slate-800 capitalize">{title || "Tanpa Judul"}</h2>
                                    </div>
                                    <p className="text-sm text-slate-400 capitalize">{novelTitle}</p>
                                </div>

                                <div
                                    className="px-6 py-4 prose prose-slate prose-sm max-w-none leading-relaxed [&_p]:mb-4 [&_p:last-child]:mb-0 prose-blockquote:border-l-4 prose-blockquote:border-primary-300 prose-blockquote:text-slate-500 prose-blockquote:italic"
                                    dangerouslySetInnerHTML={{ __html: content }}
                                />
                            </div>
                        </motion.div>
                    </div>
                </>
            )}
        </AnimatePresence>
    );
}

function OptionsDropdown({
    open,
    canPublish,
    onPreview,
    onPublish,
    onClose,
}: {
    open: boolean;
    canPublish: boolean;
    onPreview: () => void;
    onPublish: () => void;
    onClose: () => void;
}) {
    useEffect(() => {
        if (!open) return;
        const handler = (e: MouseEvent) => {
            const target = e.target as HTMLElement;
            if (!target.closest("[data-options-dropdown]")) onClose();
        };
        document.addEventListener("mousedown", handler);
        return () => document.removeEventListener("mousedown", handler);
    }, [open, onClose]);

    return (
        <div className="relative" data-options-dropdown>
            <AnimatePresence>
                {open && (
                    <motion.div
                        className="absolute right-0 top-full mt-2 bg-white rounded-2xl shadow-xl border border-slate-100 w-52 overflow-hidden z-50"
                        initial={{ opacity: 0, y: -8, scale: 0.96 }}
                        animate={{ opacity: 1, y: 0, scale: 1 }}
                        exit={{ opacity: 0, y: -8, scale: 0.96 }}
                        transition={{ duration: 0.15 }}
                    >
                        <button
                            onClick={onPreview}
                            className="w-full flex items-center gap-3 px-4 py-3 text-sm text-slate-700 hover:bg-slate-50 transition-colors cursor-pointer"
                        >
                            <Eye className="w-4 h-4 text-slate-400" />
                            Preview
                        </button>
                    </motion.div>
                )}
            </AnimatePresence>
        </div>
    );
}

function ToolbarBtn({
    active, disabled, onClick, children, title,
}: {
    active?: boolean;
    disabled?: boolean;
    onClick: () => void;
    children: React.ReactNode;
    title?: string;
}) {
    return (
        <button
            type="button"
            title={title}
            onClick={onClick}
            disabled={disabled}
            className={`w-9 h-9 flex items-center justify-center rounded-lg transition-all cursor-pointer
                ${active ? "bg-slate-900 text-white" : "text-slate-500 hover:bg-slate-100 hover:text-slate-800"}
                ${disabled ? "opacity-30 cursor-not-allowed pointer-events-none" : ""}`}
        >
            {children}
        </button>
    );
}

interface Props {
    token: string;
    postId: string;
}

export default function CreateChapterPage({ token, postId }: Props) {
    const router = useRouter();
    const [novel, setNovel] = useState<PostModel | null>(null);
    const [title, setTitle] = useState("");
    const [publishedAt, setPublishedAt] = useState<Date>(new Date());
    const [showOptions, setShowOptions] = useState(false);
    const [showPublishConfirm, setShowPublishConfirm] = useState(false);
    const [saving, setSaving] = useState(false);
    const [showPreview, setShowPreview] = useState(false);
    const [words, setWords] = useState(0);
    const titleRef = useRef<HTMLInputElement>(null);
    const dateRef = useRef<HTMLInputElement>(null);
    const { t } = useTranslation();

    const editor = useEditor({
        immediatelyRender: false,
        extensions: [
            DocumentExtension,
            ParagraphExtension,
            TextExtension,
            BoldExtension,
            ItalicExtension,
            UnderlineExtension,
            BlockquoteExtension,
            HistoryExtension,
        ],
        content: "",
        onUpdate: ({ editor }) => {
            setWords(wordCount(editor.getHTML()));
        },
        editorProps: {
            attributes: {
                class: "outline-none min-h-[400px] px-6 py-6 text-sm text-slate-800 leading-relaxed prose prose-slate prose-sm max-w-none [&_p]:mb-4 [&_p:last-child]:mb-0 prose-blockquote:border-l-4 prose-blockquote:border-primary-300 prose-blockquote:pl-4 prose-blockquote:text-slate-500 prose-blockquote:italic",
            },
        },
    });

    const canSave = !!(title && editor && !editor.isEmpty && publishedAt);

    useEffect(() => {
        const load = async () => {
            try {
                const { data: res } = await getMyPostDetail(token, postId);
                if (res?.data) setNovel(res.data);
            } catch (err) { console.error(err); }
        };
        load();
    }, [postId, token]);

    const onSave = useCallback(async () => {
        if (!canSave || saving || !editor) return;
        if (words > 1200) {
            toast.error(t('errors.maxLength'));
            return;
        };
        setSaving(true);
        try {
            await createChapter(token, {
                title,
                description: editor.getHTML(),
                post_id: postId,
                total_words: words,
                published_at: publishedAt,
            });
            router.back();
        } catch (err: any) {
            console.error(err?.data?.message ?? err.message);
        } finally {
            setSaving(false);
        }
    }, [canSave, saving, editor, title, postId, words, publishedAt, token, router]);

    const toInputValue = (d: Date) => format(d, "yyyy-MM-dd'T'HH:mm");

    return (
        <div className="flex flex-col gap-6 w-full">
            <Breadcrumbs
                title="Dashboard"
                subtitle={[
                    { title: "Daftar Novel", href: "/user/novel" },
                    { title: novel?.title || "", href: "/user/novel" },
                    { title: "Buat Chapter Baru", href: `/user/novel/chapter/${novel?.id}/create` },
                ]}
                href="/user"
            />

            <div className="sticky top-0 z-10 bg-white border-b border-slate-100 rounded-t-xl shadow-sm">
                <div className="flex items-center justify-between px-4 py-3">
                    <div className="flex items-center gap-2">
                        <button
                            onClick={() => router.back()}
                            className="w-9 h-9 rounded-xl border border-slate-200 flex items-center justify-center hover:bg-slate-50 transition-colors cursor-pointer"
                        >
                            <svg className="w-4 h-4 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                            </svg>
                        </button>
                        <span className="text-base font-semibold text-slate-800">Tulis Bab</span>
                    </div>
                    <div className="relative flex gap-3">
                        <button
                            onClick={onSave}
                            disabled={!canSave || saving}
                            className={`px-4 py-1.5 rounded-full text-sm font-semibold border transition-all cursor-pointer
                            ${canSave && !saving
                                    ? "border-primary-500 text-primary-500 hover:bg-primary-50"
                                    : "border-slate-200 text-slate-300 cursor-not-allowed"}`}
                        >
                            {saving ? "Menyimpan..." : "Simpan"}
                        </button>
                        <button
                            onClick={() => setShowOptions((v) => !v)}
                            className="w-9 h-9 flex items-center justify-center rounded-xl border border-slate-200 hover:bg-slate-50 transition-colors cursor-pointer"
                        >
                            <ChevronDown className="w-4 h-4 text-slate-600" />
                        </button>
                        <OptionsDropdown
                            open={showOptions}
                            canPublish={words >= 800}
                            onPreview={() => { setShowOptions(false); setShowPreview(true); }}
                            onPublish={() => { setShowOptions(false); setShowPublishConfirm(true); }}
                            onClose={() => setShowOptions(false)}
                        />
                    </div>
                </div>

                <div className="flex items-center gap-2 px-4 bg-slate-50 border-t border-slate-100">
                    <input
                        ref={titleRef}
                        type="text"
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                        placeholder="Tulis judul bab..."
                        className="flex-1 py-3 bg-transparent text-sm text-slate-800 placeholder:text-slate-400 outline-none font-medium"
                    />
                </div>

                <div
                    className="flex items-center gap-2 px-4 py-2.5 bg-slate-50 border-t border-slate-100 cursor-pointer hover:bg-slate-100 transition-colors"
                    onClick={() => dateRef.current?.showPicker()}
                >
                    <Calendar className="w-4 h-4 text-slate-400 shrink-0" />
                    <span className="text-xs text-slate-400">
                        Tanggal Terbit:{" "}
                        <span className="font-semibold text-slate-700">
                            {format(publishedAt, "dd MMM yyyy, HH:mm")}
                        </span>
                    </span>
                    <input
                        ref={dateRef}
                        type="datetime-local"
                        value={toInputValue(publishedAt)}
                        min={toInputValue(new Date())}
                        onChange={(e) => e.target.value && setPublishedAt(new Date(e.target.value))}
                        className="sr-only"
                        readOnly
                    />
                </div>

                <div className="flex items-center gap-1 px-3 py-2 border-t border-slate-100 bg-white">
                    <ToolbarBtn title="Bold" active={editor?.isActive("bold")} onClick={() => editor?.chain().focus().toggleBold().run()}>
                        <Bold className="w-4 h-4" />
                    </ToolbarBtn>
                    <ToolbarBtn title="Italic" active={editor?.isActive("italic")} onClick={() => editor?.chain().focus().toggleItalic().run()}>
                        <Italic className="w-4 h-4" />
                    </ToolbarBtn>
                    <ToolbarBtn title="Underline" active={editor?.isActive("underline")} onClick={() => editor?.chain().focus().toggleUnderline().run()}>
                        <Underline className="w-4 h-4" />
                    </ToolbarBtn>
                    <ToolbarBtn title="Blockquote" active={editor?.isActive("blockquote")} onClick={() => editor?.chain().focus().toggleBlockquote().run()}>
                        <Quote className="w-4 h-4" />
                    </ToolbarBtn>
                    <div className="w-px h-5 bg-slate-200 mx-1" />
                    <ToolbarBtn title="Undo" disabled={!editor?.can().undo()} onClick={() => editor?.chain().focus().undo().run()}>
                        <Undo2 className="w-4 h-4" />
                    </ToolbarBtn>
                    <ToolbarBtn title="Redo" disabled={!editor?.can().redo()} onClick={() => editor?.chain().focus().redo().run()}>
                        <Redo2 className="w-4 h-4" />
                    </ToolbarBtn>
                    <div className="ml-auto flex items-center gap-2">
                        <button
                            onClick={() => setShowPreview(true)}
                            className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs text-slate-500 hover:bg-slate-100 transition-colors cursor-pointer"
                        >
                            <Eye className="w-3.5 h-3.5" />
                            <span>Preview</span>
                        </button>
                        <span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${wordCountColor(words)}`}>
                            {words} kata
                        </span>
                    </div>
                </div>
            </div>

            <div className="bg-white min-h-screen rounded-xl shadow-sm" onClick={() => editor?.commands.focus()}>
                <EditorContent editor={editor} />
            </div>

            <div className="sticky bottom-0 bg-green-600 px-6 py-3 flex items-center justify-end gap-2">
                <span className="text-xs text-white font-medium">{words} kata</span>
                <span className="text-xs text-green-200">(800 – 1.200 kata per bab)</span>
            </div>

            <PreviewModal
                open={showPreview}
                title={title}
                novelTitle={novel?.title ?? ""}
                content={editor?.getHTML() ?? ""}
                onClose={() => setShowPreview(false)}
            />
        </div>
    );
}