import { Head } from "@inertiajs/react";
import { useEffect, useState } from "react";
import { Check, Pencil, RefreshCw, Save } from "lucide-react";
import { useI18n } from "@/lib/i18n";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Checkbox } from "@/components/ui/checkbox";
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog";
type Plan = {
    id: number;
    slug: string;
    name: string;
    price_monthly: number | string;
    currency: string;
    duration_days: number;
    billing_interval: string;
    features: string[];
    limits: Record<string, unknown>;
    is_active: boolean;
    sort_order: number;
};

const FEATURE_LABELS: Record<string, string> = {
    chart: "Charts",
    basic_indicators: "Basic indicators",
    watchlist: "Watchlist",
    price_alerts: "Price alerts",
    smc: "SMC",
    macro_insight: "Macro insight",
    signals: "Signals",
    cross_market: "Cross-market",
    advanced_alerts: "Advanced alerts",
    backtest: "Backtest",
    advanced_insight: "Advanced insight",
};

const csrf = () =>
    document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')
        ?.content ?? "";

function formatPrice(plan: Plan) {
    const value = Number(plan.price_monthly);
    if (value === 0) return "Free";
    return new Intl.NumberFormat("en-US", {
        style: "currency",
        currency: plan.currency || "USD",
        maximumFractionDigits: 2,
    }).format(value);
}

export default function SubscriptionPlans() {
    const { t } = useI18n();
    const [plans, setPlans] = useState<Plan[]>([]);
    const [editing, setEditing] = useState<Plan | null>(null);
    const [featuresText, setFeaturesText] = useState("");
    const [limitsText, setLimitsText] = useState("{}");
    const [message, setMessage] = useState("");
    const [loading, setLoading] = useState(false);

    const load = async () => {
        setLoading(true);
        try {
            const response = await fetch("/admin/subscription-plans/data", {
                headers: { Accept: "application/json" },
            });
            if (!response.ok)
                throw new Error("Unable to load subscription plans.");
            setPlans(await response.json());
        } catch (error) {
            setMessage(
                error instanceof Error
                    ? error.message
                    : "Unable to load plans.",
            );
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        void load();
    }, []);

    const startEdit = (plan: Plan) => {
        setEditing({ ...plan });
        setFeaturesText((plan.features ?? []).join("\n"));
        setLimitsText(JSON.stringify(plan.limits ?? {}, null, 2));
        setMessage("");
    };

    const save = async () => {
        if (!editing) return;
        let limits: Record<string, unknown>;
        try {
            limits = JSON.parse(limitsText || "{}");
        } catch {
            setMessage("Limits must contain valid JSON.");
            return;
        }

        const response = await fetch(
            `/admin/subscription-plans/${editing.id}`,
            {
                method: "PUT",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                    "X-CSRF-TOKEN": csrf(),
                },
                body: JSON.stringify({
                    slug: editing.slug,
                    name: editing.name,
                    price_monthly: Number(editing.price_monthly),
                    currency: editing.currency.toUpperCase(),
                    duration_days: Number(editing.duration_days),
                    billing_interval: editing.billing_interval,
                    features: featuresText
                        .split("\n")
                        .map((v) => v.trim())
                        .filter(Boolean),
                    limits,
                    is_active: editing.is_active,
                    sort_order: Number(editing.sort_order),
                }),
            },
        );

        const payload = await response.json().catch(() => ({}));
        if (!response.ok) {
            setMessage(payload.message ?? "Unable to save subscription plan.");
            return;
        }

        setMessage("Subscription plan saved.");
        setEditing(null);
        await load();
    };

    return (
        <>
            <Head title={t("admin.nav.subscriptions", "Subscriptions")} />
            <div className="p-3 sm:p-4 lg:p-6">
                <div className="mx-auto w-full max-w-6xl">
                    <div className="mb-6 flex flex-col gap-4 border-b border-border/60 pb-5 sm:flex-row sm:items-end sm:justify-between">
                        <div>
                            <h1 className="text-2xl font-semibold">
                                {t("Subscriptions")}</h1>
                            <p className="mt-1 text-sm text-muted-foreground">
                                {t("Manage subscription plans, pricing, access features, and limits.")}</p>
                        </div>
                        <div className="flex gap-2">
                            <Button
                                variant="outline"
                                type="button"
                                onClick={() => void load()}
                                disabled={loading}
                                className="inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm hover:bg-muted disabled:opacity-50"
                            >
                                <RefreshCw className="size-4" /> {t("Refresh")}</Button>
                        </div>
                    </div>

                    {message && (
                        <div className="mb-4 rounded-lg border bg-card px-4 py-3 text-sm">
                            {message}
                        </div>
                    )}

                    <div className="grid gap-5 md:grid-cols-2">
                        {plans.map((plan) => (
                            <Card
                                key={plan.id}
                                className="rounded-2xl border border-border/70 bg-card p-5 shadow-sm transition-colors hover:bg-muted/10"
                            >
                                <div className="flex items-start justify-between gap-4">
                                    <div>
                                        <div className="flex items-center gap-2">
                                            <h2 className="text-xl font-semibold">
                                                {plan.name}
                                            </h2>
                                            <Badge
                                                variant="outline"
                                                className="font-mono"
                                            >
                                                {plan.slug}
                                            </Badge>
                                        </div>
                                        <p className="mt-2 text-2xl font-bold">
                                            {formatPrice(plan)}
                                        </p>
                                        <p className="text-sm text-muted-foreground">
                                            {plan.billing_interval} ·{" "}
                                            {plan.duration_days} {t("days")}</p>
                                    </div>
                                    <Badge
                                        variant={
                                            plan.is_active
                                                ? "default"
                                                : "secondary"
                                        }
                                    >
                                        {plan.is_active ? "Active" : "Inactive"}
                                    </Badge>
                                </div>

                                <div className="mt-5">
                                    <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                                        {t("Features")}</p>
                                    <div className="grid gap-2 sm:grid-cols-2">
                                        {(plan.features ?? []).map(
                                            (feature) => (
                                                <div
                                                    key={feature}
                                                    className="flex items-center gap-2 text-sm"
                                                >
                                                    <Check className="size-4 text-success-500" />
                                                    {FEATURE_LABELS[feature] ??
                                                        feature}
                                                </div>
                                            ),
                                        )}
                                    </div>
                                </div>

                                <div className="mt-5 rounded-xl border bg-muted/30 p-3">
                                    <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                                        {t("Limits")}</p>
                                    <pre className="mt-2 overflow-auto text-xs">
                                        {JSON.stringify(
                                            plan.limits ?? {},
                                            null,
                                            2,
                                        )}
                                    </pre>
                                </div>

                                <Button
                                    variant="outline"
                                    type="button"
                                    onClick={() => startEdit(plan)}
                                    className="mt-5 inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium hover:bg-muted"
                                >
                                    <Pencil className="size-4" /> {t("Edit plan")}</Button>
                            </Card>
                        ))}
                    </div>

                    {editing && (
                        <Dialog
                            open={Boolean(editing)}
                            onOpenChange={(open) => {
                                if (!open) setEditing(null);
                            }}
                        >
                            <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
                                <DialogHeader>
                                    <DialogTitle>
                                        {`Edit ${editing.name}`}
                                    </DialogTitle>
                                    <DialogDescription>
                                        {t("System plan:")}{editing.slug}{t(". Update pricing, duration, features, limits, and activation state.")}</DialogDescription>
                                </DialogHeader>

                                <div className="grid gap-4 sm:grid-cols-2">
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Slug")}<Input
                                            value={editing.slug}
                                            disabled={editing.slug === "free" || editing.slug === "pro"}
                                            onChange={(event) =>
                                                setEditing({
                                                    ...editing,
                                                    slug: event.target.value,
                                                })
                                            }
                                            placeholder="pro"
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Name")}<Input
                                            value={editing.name}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    name: e.target.value,
                                                })
                                            }
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Currency")}<Input
                                            maxLength={3}
                                            value={editing.currency}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    currency: e.target.value,
                                                })
                                            }
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Monthly price")}<Input
                                            type="number"
                                            min="0"
                                            step="0.01"
                                            value={editing.price_monthly}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    price_monthly:
                                                        e.target.value,
                                                })
                                            }
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Duration days")}<Input
                                            type="number"
                                            min="1"
                                            value={editing.duration_days}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    duration_days: Number(
                                                        e.target.value,
                                                    ),
                                                })
                                            }
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Billing interval")}<Input
                                            value={editing.billing_interval}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    billing_interval:
                                                        e.target.value,
                                                })
                                            }
                                        />
                                    </Label>
                                    <Label className="grid gap-1.5 text-sm">
                                        {t("Sort order")}<Input
                                            type="number"
                                            min="0"
                                            value={editing.sort_order}
                                            onChange={(e) =>
                                                setEditing({
                                                    ...editing,
                                                    sort_order: Number(
                                                        e.target.value,
                                                    ),
                                                })
                                            }
                                        />
                                    </Label>
                                </div>

                                <Label className="grid gap-1.5 text-sm">
                                    {t("Features")}<span className="text-xs text-muted-foreground">
                                        {t("One feature key per line.")}</span>
                                    <Textarea
                                        className="min-h-40 font-mono text-xs"
                                        value={featuresText}
                                        onChange={(e) =>
                                            setFeaturesText(e.target.value)
                                        }
                                    />
                                </Label>
                                <Label className="grid gap-1.5 text-sm">
                                    {t("Limits JSON")}<Textarea
                                        className="min-h-32 font-mono text-xs"
                                        value={limitsText}
                                        onChange={(e) =>
                                            setLimitsText(e.target.value)
                                        }
                                    />
                                </Label>

                                <Label className="flex items-center gap-2 text-sm">
                                    <Checkbox
                                        checked={editing.is_active}
                                        onCheckedChange={(checked) =>
                                            setEditing({
                                                ...editing,
                                                is_active: checked === true,
                                            })
                                        }
                                    />
                                    {t("Plan is active")}</Label>

                                <DialogFooter>
                                    <Button
                                        type="button"
                                        variant="outline"
                                        onClick={() => setEditing(null)}
                                    >
                                        {t("Cancel")}</Button>
                                    <Button
                                        type="button"
                                        onClick={() => void save()}
                                    >
                                        <Save className="size-4" /> {t("Save changes")}</Button>
                                </DialogFooter>
                            </DialogContent>
                        </Dialog>
                    )}
                </div>
            </div>
        </>
    );
}
