"use client";

import { useTranslation } from "@/hooks/useTranslation";
import { getMyPostDetail, updatePost } from "@/libs/axios/modules/post";
import { GenreModel, PostModel, TagModel } from "@/models";
import { X } from "lucide-react";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import Breadcrumbs from "../../components/Breadcrumbs";
import { CoverUpload } from "./components/CoverUpload";

type AgeRange = { title: string; start: number; end: number };
type Step1Data = { title: string; targetAudience: string; targetAudienceAge: AgeRange | null; hasSubmit: boolean | null };
type Step2Data = { type: string; genre: GenreModel | null; tags: TagModel[]; blurb: string };
type FormData = Step1Data & Step2Data & { cover: string };

const TARGET_AUDIENCES = [
    { value: "male", label: "Laki-laki" },
    { value: "female", label: "Perempuan" },
];

const AGE_RANGES: AgeRange[] = [
    { title: "5+", start: 5, end: 12 },
    { title: "13+", start: 13, end: 17 },
    { title: "18+", start: 18, end: 100 },
];

const NOVEL_TYPES = [
    { value: "original", label: "Original", desc: "Karya asli buatan sendiri." },
    { value: "fan fiction", label: "Fan Fiction", desc: "Mengandung karakter/tokoh yang sudah ada." },
];

const MAX_BLURB_WORDS = 100;

function wordCount(text: string) {
    return text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
}

function FieldWrapper({ label, children }: { label: string; children: React.ReactNode }) {
    return (
        <div className="flex flex-col gap-1.5">
            <label className="text-sm font-semibold text-slate-700">{label}</label>
            {children}
        </div>
    );
}

const inputCls = "w-full px-4 py-3 rounded-xl border border-slate-200 text-sm text-slate-800 bg-white focus:outline-none focus:ring-2 focus:ring-primary-300 focus:border-primary-300 transition cursor-pointer appearance-none";

function StepIndicator({ current }: { current: number }) {
    return (
        <div className="flex items-center justify-center gap-3 py-4 border-b border-slate-100">
            {[1, 2, 3].map((step) => (
                <div key={step} className="flex items-center gap-3">
                    <div className={`w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold transition-all duration-300
                        ${step === current ? "bg-primary-500 text-white shadow-md shadow-primary-500/30 scale-110"
                            : step < current ? "bg-primary-100 text-primary-500"
                                : "bg-slate-100 text-slate-400"}`}>
                        {step < current
                            ? <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" /></svg>
                            : step}
                    </div>
                    {step < 3 && <div className={`w-10 h-0.5 rounded-full transition-all duration-300 ${step < current ? "bg-primary-300" : "bg-slate-100"}`} />}
                </div>
            ))}
        </div>
    );
}

function Step1({
    data,
    onChange,
    coverPreview,
    onCoverChange,
}: {
    data: Step1Data;
    onChange: (p: Partial<Step1Data>) => void;
    coverPreview: string;
    onCoverChange: (file: File, previewUrl: string) => void;
}) {
    return (
        <div className="flex flex-col">
            <CoverUpload image={coverPreview} onChange={onCoverChange} />
            <div className="flex flex-col gap-5 p-5">
                <FieldWrapper label="Judul Novel">
                    <input
                        type="text"
                        value={data.title}
                        onChange={(e) => onChange({ title: e.target.value })}
                        placeholder="Masukkan judul novel"
                        className={inputCls}
                    />
                </FieldWrapper>

                <FieldWrapper label="Target Pembaca">
                    <div className="relative">
                        <select value={data.targetAudience} onChange={(e) => onChange({ targetAudience: e.target.value })} className={inputCls}>
                            <option value="" disabled>Pilih target pembaca</option>
                            {TARGET_AUDIENCES.map(a => <option key={a.value} value={a.value}>{a.label}</option>)}
                        </select>
                        <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
                    </div>
                </FieldWrapper>

                <FieldWrapper label="Usia Target Pembaca">
                    <div className="relative">
                        <select
                            value={data.targetAudienceAge?.title ?? ""}
                            onChange={(e) => {
                                const found = AGE_RANGES.find(a => a.title === e.target.value);
                                if (found) onChange({ targetAudienceAge: found });
                            }}
                            className={inputCls}
                        >
                            <option value="" disabled>Pilih usia target</option>
                            {AGE_RANGES.map(a => <option key={a.title} value={a.title}>{a.title}</option>)}
                        </select>
                        <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
                    </div>
                </FieldWrapper>

                <FieldWrapper label="Apakah karya anda tersedia di platform lain?">
                    <div className="flex gap-3">
                        {[{ value: true, label: "Ya" }, { value: false, label: "Tidak" }].map((opt) => (
                            <button
                                key={String(opt.value)}
                                type="button"
                                onClick={() => onChange({ hasSubmit: opt.value })}
                                className={`flex-1 py-3 rounded-xl border-2 text-sm font-semibold transition-all cursor-pointer
                                    ${data.hasSubmit === opt.value
                                        ? "border-primary-500 bg-primary-50 text-primary-600"
                                        : "border-slate-200 text-slate-500 hover:border-slate-300"}`}
                            >
                                {opt.label}
                            </button>
                        ))}
                    </div>
                </FieldWrapper>
            </div>
        </div>
    );
}

function Step2({
    data, onChange, genres, tags,
}: {
    data: Step2Data;
    onChange: (p: Partial<Step2Data>) => void;
    genres: GenreModel[];
    tags: TagModel[];
}) {
    const words = wordCount(data.blurb);
    return (
        <div className="flex flex-col gap-5 p-5">
            <FieldWrapper label="Tipe Novel">
                <div className="flex flex-col gap-2">
                    {NOVEL_TYPES.map((opt) => (
                        <button
                            key={opt.value}
                            type="button"
                            onClick={() => onChange({ type: opt.value })}
                            className={`w-full text-left px-4 py-3.5 rounded-xl border-2 transition-all cursor-pointer
                                ${data.type === opt.value ? "border-primary-500 bg-primary-50/40" : "border-slate-200 hover:border-slate-300"}`}
                        >
                            <p className={`text-sm font-semibold ${data.type === opt.value ? "text-primary-600" : "text-slate-700"}`}>{opt.label}</p>
                            <p className={`text-xs mt-0.5 ${data.type === opt.value ? "text-primary-400" : "text-slate-400"}`}>{opt.desc}</p>
                        </button>
                    ))}
                </div>
            </FieldWrapper>

            <FieldWrapper label="Genre">
                <div className="relative">
                    <select
                        value={data.genre?.id ?? ""}
                        onChange={(e) => {
                            const found = genres.find(g => g.id === e.target.value);
                            if (found) onChange({ genre: found });
                        }}
                        className={inputCls}
                    >
                        <option value="" disabled>Pilih genre</option>
                        {genres.map(g => <option key={g.id} value={g.id}>{g.title}</option>)}
                    </select>
                    <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
                </div>
            </FieldWrapper>

            <FieldWrapper label={`Tag (${data.tags.length}/7)`}>
                <div className="flex flex-wrap gap-2 p-3 rounded-xl border border-slate-200 bg-white min-h-12">
                    {data.tags.map(tag => (
                        <span key={tag.id} className="inline-flex items-center gap-1 px-3 py-1 rounded-full bg-primary-100 text-primary-700 text-xs font-semibold">
                            {tag.title}
                            <button type="button" onClick={() => onChange({ tags: data.tags.filter(t => t.id !== tag.id) })} className="hover:text-primary-900 transition-colors cursor-pointer">
                                <X className="w-3 h-3" />
                            </button>
                        </span>
                    ))}
                    {data.tags.length < 7 && (
                        <select
                            value=""
                            onChange={(e) => {
                                const found = tags.find(t => t.id === e.target.value);
                                if (found && !data.tags.some(t => t.id === found.id)) onChange({ tags: [...data.tags, found] });
                            }}
                            className="text-xs text-slate-400 bg-transparent border-none outline-none cursor-pointer"
                        >
                            <option value="" disabled>{data.tags.length === 0 ? "Pilih tag..." : "+ Tambah tag"}</option>
                            {tags.filter(t => !data.tags.some(dt => dt.id === t.id)).map(t => <option key={t.id} value={t.id}>{t.title}</option>)}
                        </select>
                    )}
                </div>
                <p className="text-xs text-slate-400">Pilih maksimal 7 tag yang relevan dengan novelmu.</p>
            </FieldWrapper>

            <FieldWrapper label="Blurb Novel">
                <textarea
                    value={data.blurb}
                    onChange={(e) => onChange({ blurb: e.target.value })}
                    placeholder="Tulis blurb novel..."
                    rows={5}
                    className="w-full px-4 py-3 rounded-xl border border-slate-200 text-sm text-slate-800 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-primary-300 focus:border-primary-300 resize-none transition"
                />
                <p className={`text-xs ${words > MAX_BLURB_WORDS ? "text-red-500" : "text-slate-400"}`}>{words} / {MAX_BLURB_WORDS} kata</p>
            </FieldWrapper>
        </div>
    );
}

function ReviewRow({ label, value }: { label: string; value: React.ReactNode }) {
    return (
        <div className="flex flex-col gap-0.5">
            <span className="text-xs text-slate-400">{label}</span>
            <span className="text-sm font-semibold text-slate-800">{value || "-"}</span>
        </div>
    );
}

function Step3({
    data,
    coverPreview,
    onCoverChange,
}: {
    data: FormData;
    coverPreview: string;
    onCoverChange: (file: File, previewUrl: string) => void;
}) {
    return (
        <div className="flex flex-col">
            <CoverUpload image={coverPreview} onChange={onCoverChange} />
            <div className="h-1.5 bg-slate-100" />
            <div className="flex flex-col gap-5 p-5">
                <ReviewRow label="Judul Novel" value={data.title} />
                <div className="grid grid-cols-2 gap-4">
                    <ReviewRow label="Tipe Novel" value={NOVEL_TYPES.find(t => t.value === data.type)?.label} />
                    <ReviewRow label="Genre" value={data.genre?.title} />
                </div>
                <div className="grid grid-cols-2 gap-4">
                    <ReviewRow label="Target Pembaca" value={TARGET_AUDIENCES.find(a => a.value === data.targetAudience)?.label} />
                    <ReviewRow label="Usia Target" value={data.targetAudienceAge?.title} />
                </div>
                <ReviewRow
                    label="Tag"
                    value={
                        <div className="flex flex-wrap gap-1.5 mt-1">
                            {data.tags.map(tag => (
                                <span key={tag.id} className="px-2.5 py-1 rounded-full bg-slate-100 text-xs text-slate-600 font-normal">{tag.title}</span>
                            ))}
                        </div>
                    }
                />
                <ReviewRow label="Platform lain" value={data.hasSubmit ? "Ya" : "Tidak"} />
                <div>
                    <span className="text-xs text-slate-400">Blurb</span>
                    <p className="text-sm text-slate-700 leading-relaxed mt-1">{data.blurb}</p>
                </div>
            </div>
        </div>
    );
}

interface Props {
    token: string;
    postId: string;
    genres: GenreModel[];
    tags: TagModel[];
}

export default function EditNovelPage({ token, postId, genres, tags }: Props) {
    const router = useRouter();
    const { language } = useTranslation();
    const [step, setStep] = useState(1);
    const [submitting, setSubmitting] = useState(false);
    const [loading, setLoading] = useState(true);

    const [coverFile, setCoverFile] = useState<File | null>(null);
    const [coverPreview, setCoverPreview] = useState<string>("");

    const handleCoverChange = useCallback((file: File, previewUrl: string) => {
        setCoverFile(file);
        setCoverPreview(previewUrl);
    }, []);

    const [form, setForm] = useState<FormData>({
        title: "", targetAudience: "", targetAudienceAge: null, hasSubmit: null,
        type: "", genre: null, tags: [], blurb: "", cover: "",
    });

    const patch = useCallback((data: Partial<FormData>) => {
        setForm((prev) => ({ ...prev, ...data }));
    }, []);

    const parseBoolean = (val: any): boolean | null => {
        if (val === 1) return true;
        if (val === 0) return false;
        return null;
    };

    useEffect(() => {
        const load = async () => {
            try {
                const { data: res } = await getMyPostDetail(token, postId);
                if (res?.data) {
                    const novel = res.data as PostModel;
                    setForm({
                        title: novel.title,
                        targetAudience: novel.preference?.sex?.value ?? "",
                        targetAudienceAge: novel.preference?.age ?? null,
                        hasSubmit: parseBoolean(novel.has_submit),
                        type: novel.source ?? "",
                        genre: novel.genre ?? null,
                        tags: novel.tags ?? [],
                        blurb: novel.description ?? "",
                        cover: novel.image ?? "",
                    });
                    setCoverPreview(novel.image ?? "");
                }
            } catch (err: any) {
                console.error(err?.data?.message ?? err.message);
            } finally {
                setLoading(false);
            }
        };
        load();
    }, [postId, token]);

    const step1Valid = !!(coverPreview && form.title && form.targetAudience && form.targetAudienceAge && form.hasSubmit !== null);
    const step2Valid = !!(form.type && form.genre && form.tags.length > 0 && form.blurb && wordCount(form.blurb) <= MAX_BLURB_WORDS);
    const canNext = step === 1 ? step1Valid : step === 2 ? step2Valid : true;

    const onNext = async () => {
        if (step < 3) { setStep((s) => s + 1); return; }
        if (!form.targetAudienceAge || form.hasSubmit === null || !form.genre) return;

        setSubmitting(true);
        try {
            await updatePost(token, {
                id: postId,
                attachment: coverFile ?? form.cover,
                title: form.title,
                type: form.type,
                description: form.blurb,
                genre_id: form.genre.id,
                source: form.type,
                sex: form.targetAudience,
                has_submit: form.hasSubmit,
                age: form.targetAudienceAge,
                tags: form.tags.map((t) => t.id),
            });
            router.push(`/${language}/user/novel`);
        } catch (err: any) {
            console.error(err?.data?.message ?? err.message);
        } finally {
            setSubmitting(false);
        }
    };

    if (loading) {
        return (
            <div className="flex flex-col gap-6 w-full">
                <div className="w-full bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden">
                    <div className="h-48 bg-slate-100 animate-pulse" />
                    <div className="p-5 flex flex-col gap-4">
                        {[1, 2, 3].map(i => (
                            <div key={i} className="h-10 bg-slate-100 rounded-xl animate-pulse" />
                        ))}
                    </div>
                </div>
            </div>
        );
    }

    return (
        <div className="flex flex-col gap-6 w-full">
            <Breadcrumbs
                title="Dashboard"
                subtitle={[
                    { title: "Daftar Novel", href: "/user/novel" },
                    { title: "Edit Novel", href: `/user/novel/${postId}/edit` },
                ]}
                href="/user"
            />

            <div className="flex items-center gap-3 bg-white p-4 rounded-xl border border-slate-100 shadow-sm">
                <button
                    onClick={() => step > 1 ? setStep(s => s - 1) : 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>
                <div>
                    <h1 className="text-base font-semibold text-slate-900">Edit Novel</h1>
                    <p className="text-xs text-slate-400">Langkah {step} dari 3</p>
                </div>
            </div>

            <div className="w-full bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden">
                <StepIndicator current={step} />

                <div>
                    {step === 1 && (
                        <Step1
                            data={form}
                            onChange={patch}
                            coverPreview={coverPreview}
                            onCoverChange={handleCoverChange}
                        />
                    )}
                    {step === 2 && (
                        <Step2 data={form} onChange={patch} genres={genres} tags={tags} />
                    )}
                    {step === 3 && (
                        <Step3
                            data={form}
                            coverPreview={coverPreview}
                            onCoverChange={handleCoverChange}
                        />
                    )}
                </div>

                <div className="px-5 py-4 bg-white border-t border-slate-100">
                    <button
                        onClick={onNext}
                        disabled={!canNext || submitting}
                        className={`w-full py-3 rounded-xl text-sm font-semibold transition-all duration-200 cursor-pointer
                            ${canNext && !submitting
                                ? "bg-primary-500 text-white hover:bg-primary-600 shadow-md shadow-primary-500/20 hover:-translate-y-0.5 active:translate-y-0"
                                : "bg-slate-100 text-slate-400 cursor-not-allowed"
                            }`}
                    >
                        {submitting ? "Menyimpan..." : step === 3 ? "Simpan Perubahan" : "Selanjutnya"}
                    </button>
                </div>
            </div>
        </div>
    );
}