"use client";

import { useMemo } from "react";
import type { CatalogueRow, Deployment, Plan, Term, Tier } from "@/lib/api";
import { featureLabel } from "@/lib/features";

export interface PlanChoice {
    tier: Tier;
    term: Term;
    servers: number;
    features: string[];
}

/* Self-hosted sells annual only. The reason is in shared/license: an offline
 * licence cannot be revoked, so the term length IS the revocation window. */
function termsFor(deployment: Deployment): Term[] {
    return deployment === "self_hosted" ? ["annual"] : ["monthly", "annual"];
}

/*
 * PlanConfigurator is the whole of "what is this instance allowed", driven
 * entirely by the plans and catalogue it is handed.
 *
 * A feature appears because a catalogue row offers it, and shows a price because
 * that row has one. Nothing here is hardcoded per tier, which is what lets a new
 * paid add-on ship as a staff edit rather than a frontend release.
 *
 * It saves nothing and knows nothing about who is using it. Staff mount it to
 * set an entitlement; the customer purchase flow mounts the same component and
 * hands it a checkout.
 */
export default function PlanConfigurator({
    deployment,
    value,
    plans,
    catalogue,
    onChange,
    disabled,
}: {
    deployment: Deployment;
    value: PlanChoice;
    plans: Plan[];
    catalogue: CatalogueRow[];
    onChange: (next: PlanChoice) => void;
    disabled?: boolean;
}) {
    const available = useMemo(
        () => plans.filter((p) => p.deployment === deployment && p.active),
        [plans, deployment],
    );
    const plan = available.find((p) => p.tier === value.tier);
    const rows = useMemo(
        () => catalogue.filter((r) => r.deployment === deployment && r.tier === value.tier),
        [catalogue, deployment, value.tier],
    );
    const featureRows = rows.filter((r) => r.kind === "feature");
    const base = plan?.base_limits.max_servers ?? 0;
    const extra = Math.max(0, value.servers - base);

    const priceOf = (r: CatalogueRow) =>
        r.price_ids?.sandbox?.[value.term] ?? r.price_ids?.production?.[value.term] ?? "";

    return (
        <div className="space-y-4">
            <fieldset className="space-y-1.5">
                <legend className="text-[0.78rem] text-ink-3">Tier</legend>
                <div className="flex flex-wrap gap-2">
                    {available.map((p) => (
                        <button
                            key={p.tier}
                            type="button"
                            disabled={disabled}
                            onClick={() =>
                                onChange({
                                    ...value,
                                    tier: p.tier,
                                    /* Moving tier moves the floor, so clamp up
                                     * rather than leaving an invalid count the
                                     * backend would refuse. */
                                    servers: Math.max(value.servers, p.base_limits.max_servers),
                                })
                            }
                            className={`rounded border px-3 py-1.5 text-[0.85rem] ${
                                p.tier === value.tier
                                    ? "border-accent text-accent"
                                    : "border-rule text-ink-2"
                            }`}
                        >
                            {p.name}
                        </button>
                    ))}
                </div>
            </fieldset>

            <fieldset className="space-y-1.5">
                <legend className="text-[0.78rem] text-ink-3">Term</legend>
                <div className="flex flex-wrap gap-2">
                    {termsFor(deployment).map((t) => (
                        <button
                            key={t}
                            type="button"
                            disabled={disabled}
                            onClick={() => onChange({ ...value, term: t })}
                            className={`rounded border px-3 py-1.5 text-[0.85rem] ${
                                t === value.term
                                    ? "border-accent text-accent"
                                    : "border-rule text-ink-2"
                            }`}
                        >
                            {t === "monthly" ? "Monthly" : "Annual"}
                        </button>
                    ))}
                </div>
                {deployment === "self_hosted" && (
                    <p className="text-[0.72rem] text-ink-3">
                        Self-hosted is annual only.
                    </p>
                )}
            </fieldset>

            <label className="block">
                <span className="mb-1 block text-[0.78rem] text-ink-3">Servers</span>
                <input
                    type="number"
                    min={base}
                    value={value.servers}
                    disabled={disabled}
                    onChange={(e) =>
                        onChange({ ...value, servers: Number(e.target.value) })
                    }
                    className="w-28 rounded border border-rule bg-panel px-2 py-1.5 text-[0.85rem] text-ink"
                />
                <span className="ml-2 text-[0.78rem] text-ink-3">
                    {base} included{extra > 0 ? `, ${extra} extra` : ""}
                </span>
            </label>

            {featureRows.length > 0 && (
                <fieldset className="space-y-1.5">
                    <legend className="text-[0.78rem] text-ink-3">Features</legend>
                    {featureRows.map((r) => {
                        const key = r.feature_key!;
                        const on = value.features.includes(key);
                        const priced = priceOf(r) !== "";
                        return (
                            <label
                                key={key}
                                className="flex items-center gap-2 text-[0.85rem] text-ink-2"
                            >
                                <input
                                    type="checkbox"
                                    checked={on}
                                    disabled={disabled}
                                    onChange={(e) =>
                                        onChange({
                                            ...value,
                                            features: e.target.checked
                                                ? [...value.features, key]
                                                : value.features.filter((f) => f !== key),
                                        })
                                    }
                                />
                                <span>{featureLabel(key)}</span>
                                <span className="text-[0.72rem] text-ink-3">
                                    {priced ? "paid add-on" : "included"}
                                </span>
                            </label>
                        );
                    })}
                </fieldset>
            )}
        </div>
    );
}
