import { Head, Link } from "@inertiajs/react";
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
import { Copy, RefreshCw, Users, WalletCards, ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";

import { useI18n } from "@/lib/i18n";
import AppLayout from "@/layouts/app-layout";
type ReferralData = {
    code: string;
    referrals: number;
    max_referrals: number;
    credit_balance: number;
};

export default function Referrals() {
    const { t } = useI18n();
    const [data, setData] = useState<ReferralData | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [copied, setCopied] = useState(false);
    const [copyError, setCopyError] = useState<string | null>(null);
    const requestRef = useRef<AbortController | null>(null);
    const copyTimerRef = useRef<number | null>(null);

    const load = useCallback(async () => {
        requestRef.current?.abort();
        const controller = new AbortController();
        requestRef.current = controller;
        setLoading(true);
        setError(null);

        try {
            const response = await fetch("/referrals/data", {
                headers: { Accept: "application/json" },
                credentials: "same-origin",
                cache: "no-store",
                signal: controller.signal,
            });

            if (!response.ok) {
                throw new Error(
                    t("Unable to load referral data (HTTP :status).", {
                        status: response.status,
                    }),
                );
            }

            const payload = (await response.json()) as ReferralData;
            if (
                !payload ||
                typeof payload.code !== "string" ||
                !Number.isFinite(Number(payload.referrals)) ||
                !Number.isFinite(Number(payload.max_referrals)) ||
                !Number.isFinite(Number(payload.credit_balance))
            ) {
                throw new Error(t("Invalid referral data format."));
            }

            if (!controller.signal.aborted) setData(payload);
        } catch (reason) {
            if (
                controller.signal.aborted ||
                (reason instanceof DOMException && reason.name === "AbortError")
            ) {
                return;
            }
            setError(
                reason instanceof Error
                    ? reason.message
                    : t("Unable to load referral data."),
            );
        } finally {
            if (requestRef.current === controller) {
                requestRef.current = null;
                setLoading(false);
            }
        }
    }, []);

    useEffect(() => {
        void load();
        return () => {
            requestRef.current?.abort();
            requestRef.current = null;
            if (copyTimerRef.current !== null) {
                window.clearTimeout(copyTimerRef.current);
                copyTimerRef.current = null;
            }
        };
    }, [load]);

    const link =
        data && typeof window !== "undefined"
            ? `${window.location.origin}/register?ref=${encodeURIComponent(data.code)}`
            : "";

    const copy = async () => {
        if (!link) return;
        setCopyError(null);
        try {
            await navigator.clipboard.writeText(link);
            setCopied(true);
            if (copyTimerRef.current !== null) {
                window.clearTimeout(copyTimerRef.current);
            }
            copyTimerRef.current = window.setTimeout(() => {
                setCopied(false);
                copyTimerRef.current = null;
            }, 1600);
        } catch {
            setCopied(false);
            setCopyError(
                t("Clipboard is unavailable. Copy the link manually."),
            );
        }
    };

    const creditBalance = Number(data?.credit_balance ?? 0);
    const maxReferrals = Number(data?.max_referrals ?? 0);
    const referralCount = Number(data?.referrals ?? 0);
    const progress =
        maxReferrals > 0
            ? Math.min(100, Math.max(0, (referralCount / maxReferrals) * 100))
            : 0;

    return (
        <>
            <Head title={t("Referral Program")} />
            <div className="product-page min-h-screen bg-background text-foreground">
                <div className="product-page-content mx-auto w-full max-w-6xl">
                    <div className="mb-8 flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
                        <div>
                            <p className="mb-2 text-[10px] font-bold uppercase tracking-[0.2em] text-muted-foreground">{t("Account / Referrals")}</p>
                            <h1 className="text-2xl font-bold sm:text-3xl">
                                {t("Referral Program")}
                            </h1>
                            <p className="mt-2 max-w-2xl text-sm text-muted-foreground">
                                {t(
                                    "Invite other traders to join and use Referral Credit to reduce the Pro price.",
                                )}
                            </p>
                        </div>
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={() => void load()}
                            disabled={loading}
                            className="gap-2 self-start sm:self-auto"
                        >
                            <RefreshCw
                                className={`size-4 ${loading ? "animate-spin" : ""}`}
                            />
                            {t("Refresh")}
                        </Button>
                    </div>

                    <div className="mb-6 flex flex-wrap items-center gap-2 text-xs font-medium text-muted-foreground">
                        <Link href="/subscription/plans" className="inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 transition hover:bg-muted hover:text-foreground">
                            {t("View subscription plans")}
                            <ArrowRight className="size-3.5" />
                        </Link>
                    </div>

                    {error && (
                        <div
                            className="mb-5 flex flex-col gap-3 rounded-xl border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive sm:flex-row sm:items-center sm:justify-between"
                            role="alert"
                            aria-live="polite"
                        >
                            <span>{error}</span>
                            <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                onClick={() => void load()}
                                disabled={loading}
                            >
                                {t("Try again")}
                            </Button>
                        </div>
                    )}

                    {copyError && (
                        <div
                            className="mb-5 rounded-xl border border-warning-500/30 bg-warning-500/5 p-3 text-sm text-warning-700 dark:text-warning-300"
                            role="status"
                            aria-live="polite"
                        >
                            {copyError}
                        </div>
                    )}

                    {loading && !data && (
                        <div
                            className="grid gap-5 md:grid-cols-2"
                            role="status"
                            aria-live="polite"
                            aria-label={t("Loading referrals")}
                        >
                            <div className="h-44 animate-pulse rounded-2xl border bg-muted/30" />
                            <div className="h-44 animate-pulse rounded-2xl border bg-muted/30" />
                            <div className="h-36 animate-pulse rounded-2xl border bg-muted/30 md:col-span-2" />
                        </div>
                    )}

                    {!loading && !error && !data && (
                        <Card className="rounded-2xl border-dashed p-8 text-center text-sm text-muted-foreground">
                            {t(
                                "Referral data is not available yet. Please refresh.",
                            )}
                        </Card>
                    )}

                    {data && (
                        <>
                            <Card className="mb-6 rounded-2xl p-5 sm:p-6">
                                <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                                    {t("Referral Link")}
                                </p>
                                <div className="mt-3 flex flex-col gap-3 sm:flex-row">
                                    <div className="min-w-0 flex-1 rounded-lg border bg-muted/30 px-4 py-3 font-mono text-sm break-all">
                                        {link}
                                    </div>
                                    <Button
                                        onClick={() => void copy()}
                                        disabled={!link}
                                        className="gap-2 sm:self-start"
                                    >
                                        <Copy className="size-4" />
                                        {copied ? t("Copied") : t("Copy link")}
                                    </Button>
                                </div>
                                <p className="mt-3 text-sm text-muted-foreground">
                                    {t("Code")}:{" "}
                                    <span className="font-semibold text-foreground">
                                        {data.code}
                                    </span>
                                </p>
                            </Card>

                            <div className="grid gap-5 md:grid-cols-2">
                                <Card className="rounded-2xl p-5 sm:p-6">
                                    <div className="flex items-center gap-3">
                                        <Users className="size-5" />
                                        <div>
                                            <p className="text-sm text-muted-foreground">
                                                {t("Referrals")}
                                            </p>
                                            <p className="text-2xl font-bold tabular-nums">
                                                {referralCount} / {maxReferrals}
                                            </p>
                                        </div>
                                    </div>
                                    <div
                                        className="mt-5 h-2 overflow-hidden rounded-full bg-muted"
                                        role="progressbar"
                                        aria-label={t("Referral usage")}
                                        aria-valuemin={0}
                                        aria-valuemax={maxReferrals}
                                        aria-valuenow={Math.min(
                                            referralCount,
                                            maxReferrals,
                                        )}
                                    >
                                        <div
                                            className="h-full rounded-full bg-success-500 transition-[width]"
                                            style={{ width: `${progress}%` }}
                                        />
                                    </div>
                                </Card>

                                <Card className="rounded-2xl p-5 sm:p-6">
                                    <div className="flex items-center gap-3">
                                        <WalletCards className="size-5" />
                                        <div>
                                            <p className="text-sm text-muted-foreground">
                                                {t("Referral Credit")}
                                            </p>
                                            <p className="text-2xl font-bold tabular-nums">
                                                ${creditBalance.toFixed(2)}
                                            </p>
                                        </div>
                                    </div>
                                    <p className="mt-4 text-sm text-muted-foreground">
                                        {t(
                                            "Credit can be used as a discount when purchasing or renewing Pro.",
                                        )}
                                    </p>
                                </Card>
                            </div>
                        </>
                    )}
                </div>
            </div>
        </>
    );
}

Referrals.layout = (page: ReactNode) => (
    <AppLayout breadcrumbs={[{ title: "Referrals", href: "" }]}>
        {page}
    </AppLayout>
);
