import React, { useEffect, useMemo, useState } from "react";
import { Formik } from "formik";
import * as Yup from "yup";
import type { KingverseSettings } from "../api";
import { fetchSettings, updateSettings, uploadSettingsLogo } from "../api";
import { Button, TextArea, TextInput, useNinjaSfx, useToast } from "../ui";

type FormValues = {
    brand: string;
    subtitle: string;
    logo_url: string;

    banner_title: string;
    banner_subtitle: string;
    banner_button_text: string;
    banner_button_url: string;

    leaderboard_enabled: boolean;
    leaderboard_title: string;
    leaderboard_subtitle: string;

    payments_title: string;
    payments_methods: string;

    contacts: string;

    member_dashboard_title: string;
    member_dashboard_subtitle: string;
    member_dashboard_items: string;
};

const schema = Yup.object({
    brand: Yup.string().max(120),
    subtitle: Yup.string().max(255),
    logo_url: Yup.string().max(2048),
    banner_title: Yup.string().max(120),
    banner_subtitle: Yup.string().max(255),
    banner_button_text: Yup.string().max(60),
    banner_button_url: Yup.string().max(2048),
    leaderboard_title: Yup.string().max(120),
    leaderboard_subtitle: Yup.string().max(255),
    payments_title: Yup.string().max(120),
    contacts: Yup.string(),
    payments_methods: Yup.string(),
    member_dashboard_title: Yup.string().max(120),
    member_dashboard_subtitle: Yup.string().max(255),
    member_dashboard_items: Yup.string(),
});

function linesToText(lines?: string[] | null) {
    return (lines || []).filter(Boolean).join("\n");
}

function textToLines(text: string) {
    return text
        .split(/\r?\n/g)
        .map((v) => v.trim())
        .filter((v) => v !== "");
}

function toFormValues(s?: KingverseSettings | null): FormValues {
    return {
        brand: s?.brand ?? "",
        subtitle: s?.subtitle ?? "",
        logo_url: s?.logo_url ?? "",

        banner_title: s?.banner?.title ?? "",
        banner_subtitle: s?.banner?.subtitle ?? "",
        banner_button_text: s?.banner?.button_text ?? "",
        banner_button_url: s?.banner?.button_url ?? "",

        leaderboard_enabled: Boolean(s?.leaderboard?.enabled ?? false),
        leaderboard_title: s?.leaderboard?.title ?? "",
        leaderboard_subtitle: s?.leaderboard?.subtitle ?? "",

        payments_title: s?.payments?.title ?? "",
        payments_methods: linesToText(s?.payments?.methods),

        contacts: linesToText(s?.contacts),

        member_dashboard_title: s?.member_dashboard?.title ?? "",
        member_dashboard_subtitle: s?.member_dashboard?.subtitle ?? "",
        member_dashboard_items: linesToText(s?.member_dashboard?.items),
    };
}

function buildPayload(values: FormValues): Partial<KingverseSettings> {
    const toNull = (v: string) => {
        const s = v.trim();
        return s === "" ? null : s;
    };

    const payload: Partial<KingverseSettings> = {
        brand: toNull(values.brand),
        subtitle: toNull(values.subtitle),
        logo_url: toNull(values.logo_url),
        banner: {
            title: toNull(values.banner_title),
            subtitle: toNull(values.banner_subtitle),
            button_text: toNull(values.banner_button_text),
            button_url: toNull(values.banner_button_url),
        },
        leaderboard: {
            enabled: values.leaderboard_enabled,
            title: toNull(values.leaderboard_title),
            subtitle: toNull(values.leaderboard_subtitle),
        },
        payments: {
            title: toNull(values.payments_title),
            methods: textToLines(values.payments_methods),
        },
        contacts: textToLines(values.contacts),
        member_dashboard: {
            title: toNull(values.member_dashboard_title),
            subtitle: toNull(values.member_dashboard_subtitle),
            items: textToLines(values.member_dashboard_items),
        },
    };

    return payload;
}

export function AdminSettingsPage() {
    const { toast } = useToast();
    const sfx = useNinjaSfx();
    const [loading, setLoading] = useState(true);
    const [initial, setInitial] = useState<FormValues>(() => toFormValues(null));
    const [logoUploading, setLogoUploading] = useState(false);

    useEffect(() => {
        let active = true;
        setLoading(true);
        fetchSettings()
            .then((data) => {
                if (!active) return;
                setInitial(toFormValues(data));
            })
            .catch(() => {
                if (!active) return;
                toast("error", "Gagal memuat pengaturan.");
            })
            .finally(() => {
                if (!active) return;
                setLoading(false);
            });
        return () => {
            active = false;
        };
    }, [toast]);

    const editor = useMemo(() => {
        if (loading) {
            return (
                <div className="rounded-2xl border border-white/10 bg-white/[0.03] p-6 text-sm font-semibold text-gray-200">
                    Memuat...
                </div>
            );
        }

        return (
            <Formik<FormValues>
                initialValues={initial}
                enableReinitialize
                validationSchema={schema}
                onSubmit={async (values, helpers) => {
                    helpers.setSubmitting(true);
                    try {
                        sfx.play("save");
                        const saved = await updateSettings(buildPayload(values));
                        setInitial(toFormValues(saved));
                        toast("success", "Pengaturan tersimpan.");
                    } catch (e) {
                        toast("error", "Gagal menyimpan pengaturan.");
                    } finally {
                        helpers.setSubmitting(false);
                    }
                }}
            >
                {({ values, errors, touched, handleSubmit, handleChange, isSubmitting, setFieldValue }) => (
                    <form onSubmit={handleSubmit}>
                        <div className="ninja-card rounded-2xl border border-white/10 bg-white/[0.03] p-6 shadow-[0_20px_80px_-40px_rgba(0,0,0,0.9)] backdrop-blur">
                            <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
                                <div>
                                    <div className="text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                        Kustomisasi
                                    </div>
                                    <div className="mt-1 text-2xl font-semibold tracking-tight text-white font-ninja">
                                        <span className="text-[#FFD700]">Brand</span> Settings
                                    </div>
                                    <div className="mt-1 text-sm text-gray-300/80">
                                        Logo, nama website, banner, leaderboard, dan kontak.
                                    </div>
                                </div>
                                <div className="flex items-center gap-2">
                                    <Button type="submit" disabled={isSubmitting} tip="Simpan perubahan">
                                        {isSubmitting ? "Menyimpan..." : "Simpan"}
                                    </Button>
                                </div>
                            </div>

                            <div className="mt-6 grid grid-cols-1 gap-4 lg:grid-cols-12">
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Nama Website"
                                    name="brand"
                                    value={values.brand}
                                    onChange={handleChange}
                                    error={touched.brand ? (errors.brand as string) : null}
                                    placeholder="Contoh: 🏯 KING VERSE JOKI"
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Subtitle"
                                    name="subtitle"
                                    value={values.subtitle}
                                    onChange={handleChange}
                                    error={touched.subtitle ? (errors.subtitle as string) : null}
                                    placeholder="Contoh: Layanan Joki & Automasi"
                                />

                                <div className="lg:col-span-12">
                                    <div className="rounded-2xl border border-white/10 bg-black/10 p-4">
                                        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
                                            <div>
                                                <div className="text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                                    Logo
                                                </div>
                                                <div className="mt-1 text-sm font-semibold text-white">
                                                    Upload logo (png/jpg/webp/svg, max 2MB)
                                                </div>
                                            </div>
                                            <div className="flex items-center gap-3">
                                                {values.logo_url ? (
                                                    <img
                                                        src={values.logo_url}
                                                        alt="Logo"
                                                        className="h-10 w-10 rounded-xl border border-white/10 bg-white/5 object-contain"
                                                    />
                                                ) : (
                                                    <div className="grid h-10 w-10 place-items-center rounded-xl border border-white/10 bg-white/5 text-xs font-semibold text-gray-200">
                                                        —
                                                    </div>
                                                )}
                                                <label
                                                    data-tip="Upload logo"
                                                    className="ninja-tip inline-flex cursor-pointer items-center gap-2 rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold text-gray-100 transition duration-300 hover:bg-white/10"
                                                >
                                                    <input
                                                        type="file"
                                                        accept="image/png,image/jpeg,image/webp,image/svg+xml"
                                                        className="hidden"
                                                        disabled={logoUploading}
                                                        onChange={async (e) => {
                                                            const target = e.target;
                                                            const file = target.files?.[0];
                                                            target.value = "";
                                                            if (!file) return;
                                                            sfx.play("upload");
                                                            setLogoUploading(true);
                                                            try {
                                                                const res = await uploadSettingsLogo(file);
                                                                setFieldValue("logo_url", res.logo_url);
                                                                toast("success", "Logo terupload.");
                                                            } catch (err) {
                                                                toast("error", "Gagal upload logo.");
                                                            } finally {
                                                                setLogoUploading(false);
                                                            }
                                                        }}
                                                    />
                                                    {logoUploading ? "Uploading..." : "Upload"}
                                                </label>
                                            </div>
                                        </div>
                                        <TextInput
                                            className="mt-3"
                                            label="Logo URL"
                                            name="logo_url"
                                            value={values.logo_url}
                                            onChange={handleChange}
                                            error={touched.logo_url ? (errors.logo_url as string) : null}
                                            placeholder="Auto terisi setelah upload"
                                        />
                                    </div>
                                </div>

                                <div className="lg:col-span-12">
                                    <div className="mt-2 text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                        Banner
                                    </div>
                                </div>
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Judul Banner"
                                    name="banner_title"
                                    value={values.banner_title}
                                    onChange={handleChange}
                                    error={touched.banner_title ? (errors.banner_title as string) : null}
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Subtitle Banner"
                                    name="banner_subtitle"
                                    value={values.banner_subtitle}
                                    onChange={handleChange}
                                    error={touched.banner_subtitle ? (errors.banner_subtitle as string) : null}
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Teks Tombol"
                                    name="banner_button_text"
                                    value={values.banner_button_text}
                                    onChange={handleChange}
                                    error={touched.banner_button_text ? (errors.banner_button_text as string) : null}
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="URL Tombol"
                                    name="banner_button_url"
                                    value={values.banner_button_url}
                                    onChange={handleChange}
                                    error={touched.banner_button_url ? (errors.banner_button_url as string) : null}
                                    placeholder="https://..."
                                />

                                <div className="lg:col-span-12">
                                    <div className="mt-4 flex items-center justify-between gap-3">
                                        <div className="text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                            Leaderboard
                                        </div>
                                        <label className="inline-flex select-none items-center gap-2 text-sm font-semibold text-gray-100">
                                            <input
                                                type="checkbox"
                                                checked={values.leaderboard_enabled}
                                                onChange={(e) =>
                                                    setFieldValue(
                                                        "leaderboard_enabled",
                                                        e.currentTarget.checked,
                                                    )
                                                }
                                                className="h-4 w-4 rounded border border-white/20 bg-white/5 text-fuchsia-500 focus:ring-fuchsia-500/60"
                                            />
                                            Aktif
                                        </label>
                                    </div>
                                </div>
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Judul Leaderboard"
                                    name="leaderboard_title"
                                    value={values.leaderboard_title}
                                    onChange={handleChange}
                                    error={touched.leaderboard_title ? (errors.leaderboard_title as string) : null}
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Subtitle Leaderboard"
                                    name="leaderboard_subtitle"
                                    value={values.leaderboard_subtitle}
                                    onChange={handleChange}
                                    error={touched.leaderboard_subtitle ? (errors.leaderboard_subtitle as string) : null}
                                />

                                <div className="lg:col-span-12">
                                    <div className="mt-4 text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                        Pembayaran
                                    </div>
                                </div>
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Judul Pembayaran"
                                    name="payments_title"
                                    value={values.payments_title}
                                    onChange={handleChange}
                                    error={touched.payments_title ? (errors.payments_title as string) : null}
                                />
                                <TextArea
                                    className="lg:col-span-6"
                                    label="Metode Pembayaran (1 baris per item)"
                                    name="payments_methods"
                                    value={values.payments_methods}
                                    onChange={handleChange}
                                    error={touched.payments_methods ? (errors.payments_methods as string) : null}
                                    rows={4}
                                    placeholder={"QRIS\nDANA\nGOPAY"}
                                />

                                <div className="lg:col-span-12">
                                    <div className="mt-4 text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                        Kontak
                                    </div>
                                </div>
                                <TextArea
                                    className="lg:col-span-12"
                                    label="Kontak (1 baris per item)"
                                    name="contacts"
                                    value={values.contacts}
                                    onChange={handleChange}
                                    error={touched.contacts ? (errors.contacts as string) : null}
                                    rows={4}
                                    placeholder={"📞 WA : 08xxxx\n💬 Facebook: ...\n💻 Discord: ..."}
                                />

                                <div className="lg:col-span-12">
                                    <div className="mt-4 text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                                        Member Dashboard
                                    </div>
                                </div>
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Judul"
                                    name="member_dashboard_title"
                                    value={values.member_dashboard_title}
                                    onChange={handleChange}
                                    error={
                                        touched.member_dashboard_title
                                            ? (errors.member_dashboard_title as string)
                                            : null
                                    }
                                />
                                <TextInput
                                    className="lg:col-span-6"
                                    label="Subtitle"
                                    name="member_dashboard_subtitle"
                                    value={values.member_dashboard_subtitle}
                                    onChange={handleChange}
                                    error={
                                        touched.member_dashboard_subtitle
                                            ? (errors.member_dashboard_subtitle as string)
                                            : null
                                    }
                                />
                                <TextArea
                                    className="lg:col-span-12"
                                    label="Items (1 baris per item)"
                                    name="member_dashboard_items"
                                    value={values.member_dashboard_items}
                                    onChange={handleChange}
                                    error={
                                        touched.member_dashboard_items
                                            ? (errors.member_dashboard_items as string)
                                            : null
                                    }
                                    rows={6}
                                />
                            </div>
                        </div>
                    </form>
                )}
            </Formik>
        );
    }, [initial, loading, logoUploading, toast]);

    return <div>{editor}</div>;
}
