"use client";

import { createPost, CreatePostBody } from "@/libs/axios/modules/post";
import { useTranslation } from "@/hooks/useTranslation";
import { GenreModel, TagModel } from "@/models";
import { X } from "lucide-react";
import { useRouter } from "next/navigation";
import { useCallback, useState } from "react";
import Breadcrumbs from "../../components/Breadcrumbs";
import { CoverUpload } from "./components/CoverUpload";
import { SearchableMultiSelect, SearchableSelect } from "./components/SearchableSelect";

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;

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">
                <SearchableSelect
                    value={data.genre}
                    options={genres}
                    onSelect={(genre) => onChange({ genre })}
                    placeholder="Pilih genre"
                />
            </FieldWrapper>

            <FieldWrapper label={`Tag (${data.tags.length}/7)`}>
                <div className="flex flex-wrap items-center 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>
                    ))}
                    <SearchableMultiSelect
                        options={tags}
                        excludeIds={data.tags.map(t => t.id)}
                        onAdd={(tag) => onChange({ tags: [...data.tags, tag] })}
                        placeholder={data.tags.length === 0 ? "Pilih tag..." : "+ Tambah tag"}
                        disabled={data.tags.length >= 7}
                    />
                </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;
    genres: GenreModel[];
    tags: TagModel[];
}

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

    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: "",
    });

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

    const step1Valid = !!(coverFile && 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 || !coverFile) return;

        setSubmitting(true);
        try {
            const attachmentUrl = URL.createObjectURL(coverFile);

            const body: CreatePostBody = {
                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: {
                    title: form.targetAudienceAge.title,
                    start: form.targetAudienceAge.start,
                    end: form.targetAudienceAge.end,
                },
                tags: form.tags.map((t) => t.id),
                attachment: coverFile,
            };

            const { data: res } = await createPost(token, body);
            if (res?.data) router.push(`/${language}/user/novel`);
        } catch (err: any) {
            console.error(err?.data?.message ?? err.message);
        } finally {
            setSubmitting(false);
        }
    };

    return (
        <div className="flex flex-col gap-6 w-full">
            <Breadcrumbs
                title="Dashboard"
                subtitle={[
                    { title: "Daftar Novel", href: "/user/novel" },
                    { title: "Buat Novel Baru", href: "/user/novel/create" },
                ]}
                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">Buat Novel Baru</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 ? "Buat Novel" : "Selanjutnya"}
                    </button>
                </div>
            </div>
        </div>
    );
}