"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import { API_BASE, ApiError, NotConnected, api } from "@/lib/api";
import { NotConnectedPanel } from "@/components/NotConnected";
import { LicenceDelivery } from "@/components/LicenceDelivery";
import { MembersPanel } from "@/components/MembersPanel";
import { RelinkPanel } from "@/components/RelinkPanel";
import { StatePill } from "@/components/StatePill";
import { PageFrame, RailCard, RailFacts } from "@/components/PageFrame";
import { PageHeader } from "@/components/PageHeader";
import { formatDate, licenceState, limitLabel } from "@/lib/format";
import { featureLabel } from "@/lib/features";

export default function InstancePage() {
    const id = String(useParams().id);
    const router = useRouter();
    const qc = useQueryClient();
    const [relinkError, setRelinkError] = useState<string | undefined>();

    const account = useQuery({ queryKey: ["account"], queryFn: api.account });
    const licence = useQuery({
        queryKey: ["license", id],
        queryFn: () => api.license(id),
        retry: false,
    });

    const relink = useMutation({
        mutationFn: (newId: string) => api.relink(id, newId),
        onSuccess: (lic) => {
            qc.invalidateQueries({ queryKey: ["account"] });
            router.replace(`/instances/${lic.instance_id}`);
        },
        onError: (err) =>
            setRelinkError(err instanceof ApiError ? err.message : "Relink failed. Try again."),
    });

    if (account.error instanceof NotConnected) return <NotConnectedPanel url={API_BASE} />;

    const instance = account.data?.instances.find((i) => i.instance_id === id);
    if (account.isLoading) return <p className="text-ink-3">Loading…</p>;
    if (!instance) {
        // Says "not on your account" rather than "does not exist": the backend
        // answers 404 for another account's instance, and confirming existence
        // here would undo that.
        return <p className="text-ink-2">That instance is not on your account.</p>;
    }

    const lic = licence.data;
    const state = licenceState(lic?.expires_at, Boolean(lic));
    const cloud = instance.deployment === "cloud";

    return (
        <div className="grid gap-6">
            <PageHeader
                back={{ href: "/", label: "Overview" }}
                title={instance.name || "Unnamed instance"}
                subtitle={`${cloud ? "Cloud" : "Self-hosted"}${
                    instance.tier ? ` · ${instance.tier.replace("_", " ")}` : ""
                } · created ${formatDate(instance.created_at)}`}
                record={[
                    { key: "Instance", value: instance.instance_id, copy: true },
                    ...(lic ? [{ key: "Licence", value: lic.license_id, copy: true }] : []),
                ]}
                status={<StatePill state={state} />}
            />

            <PageFrame
                aside={
                    <>
                        <RailCard title="Licence">
                            {lic ? (
                                <RailFacts
                                    rows={[
                                        { label: "Tier", value: lic.tier.replace("_", " ") },
                                        { label: "Issued", value: formatDate(lic.issued_at) },
                                        { label: "Expires", value: formatDate(lic.expires_at) },
                                        { label: "Reason", value: lic.reason },
                                    ]}
                                />
                            ) : (
                                <p className="text-[0.82rem] text-ink-2">
                                    No licence issued yet.
                                </p>
                            )}
                        </RailCard>

                        {lic && (
                            <RailCard title="Included">
                                <RailFacts
                                    rows={[
                                        {
                                            label: "Servers",
                                            value: limitLabel(lic.limits.max_servers),
                                        },
                                        {
                                            label: "Secret groups",
                                            value: limitLabel(lic.limits.max_secret_groups),
                                        },
                                        {
                                            label: "Channels",
                                            value: limitLabel(lic.limits.max_channels),
                                        },
                                        {
                                            label: "Features",
                                            // Labelled, not raw keys: this is
                                            // the customer's own licence, and
                                            // "vuln_scanning" is not a name
                                            // anyone bought.
                                            value: lic.features.map(featureLabel).join(", ") || "none",
                                        },
                                    ]}
                                />
                            </RailCard>
                        )}

                        {!cloud && (
                            <RailCard title="Moves">
                                <RailFacts
                                    rows={[
                                        {
                                            label: "Relinks used",
                                            value: `${instance.relink_count} of ${
                                                account.data?.max_relinks ?? 3
                                            }`,
                                        },
                                    ]}
                                />
                                <p className="text-[0.82rem] text-ink-2">
                                    Moving a licence to a different install counts as one.
                                </p>
                            </RailCard>
                        )}
                    </>
                }
            >
                {cloud ? (
                    <MembersPanel instanceId={instance.instance_id} />
                ) : (
                    <p className="rounded border border-rule bg-panel p-5 text-ink-2">
                        Users for this install are managed inside it, in Settings → Instance. We do
                        not have access to your own deployment.
                    </p>
                )}

                {lic && !cloud && (
                    <>
                        <LicenceDelivery
                            instanceId={instance.instance_id}
                            blob={lic.blob ?? ""}
                            downloadUrl={api.licenseBlobUrl(instance.instance_id)}
                        />
                        <RelinkPanel
                            instanceId={instance.instance_id}
                            used={instance.relink_count}
                            max={account.data?.max_relinks ?? 3}
                            error={relinkError}
                            onRelink={(newId) => relink.mutate(newId)}
                        />
                    </>
                )}

                {!lic && (
                    <p className="rounded border border-rule bg-panel p-5 text-ink-2">
                        No licence has been issued for this instance yet.
                    </p>
                )}
            </PageFrame>
        </div>
    );
}
