"use client";

import { useQueries, useQuery } from "@tanstack/react-query";
import Link from "next/link";
import { API_BASE, NotConnected, api, type License } from "@/lib/api";
import { NotConnectedPanel } from "@/components/NotConnected";
import { InstanceRecord } from "@/components/InstanceRecord";
import { PageFrame, RailCard, RailFacts } from "@/components/PageFrame";
import { PageHeader } from "@/components/PageHeader";
import { LinkButton } from "@/components/Button";
import { StatePill } from "@/components/StatePill";
import { daysRemaining, formatDate, licenceState } from "@/lib/format";

export default function OverviewPage() {
    const { data, error, isLoading } = useQuery({ queryKey: ["account"], queryFn: api.account });
    const people = useQuery({ queryKey: ["account-users"], queryFn: api.accountUsers });

    const licences = useQueries({
        queries: (data?.instances ?? [])
            .filter((i) => i.current_license)
            .map((i) => ({
                queryKey: ["license", i.instance_id],
                queryFn: () => api.license(i.instance_id),
            })),
    });

    if (error instanceof NotConnected) return <NotConnectedPanel url={API_BASE} />;
    if (isLoading || !data) return <p className="text-ink-3">Loading your account…</p>;

    const byInstance = new Map<string, License>();
    licences.forEach((q) => {
        if (q.data) byInstance.set(q.data.instance_id, q.data);
    });

    const live = data.instances.filter((i) => i.status !== "deleted");

    // Work the customer has to do, gathered across every instance. This is the
    // only account-level view of it each record only knows about itself.
    const attention = live.flatMap((i) => {
        const lic = byInstance.get(i.instance_id);
        const state = licenceState(lic?.expires_at, Boolean(lic));
        if (state === "none") return [{ id: i.instance_id, text: `${i.name || "An instance"} is not linked`, note: "" }];
        if (state === "expired") return [{ id: i.instance_id, text: `${i.name} has expired`, note: "now" }];
        if (state === "warn")
            return [
                {
                    id: i.instance_id,
                    text: `${i.name} expires`,
                    note: `${daysRemaining(lic!.expires_at)}d`,
                },
            ];
        return [];
    });

    const pending = (people.data ?? []).filter((p) => !p.verified_at).length;

    const subtitle =
        live.length === 0 ? "Nothing here yet." : `${live.length} ${live.length === 1 ? "instance" : "instances"}${attention.length ? ` · ${attention.length} needing attention` : " · all licensed"}`;

    return (
        <div className="grid gap-6">
            <PageHeader
                title="Overview"
                subtitle={subtitle}
                actions={live.length > 0 ? <LinkButton href="/purchase">Buy a plan</LinkButton> : undefined}
                record={[
                    { key: "Account", value: data.account.account_id, copy: true },
                    { key: "Billing", value: data.account.billing_email },
                ]}
                status={attention.length === 0 && live.length > 0 ? <StatePill state="valid" /> : undefined}
            />

            {live.length === 0 ? (
                <div className="grid max-w-xl gap-3 rounded border border-rule bg-panel p-5">
                    <h2 className="text-xl">No instances yet</h2>
                    <p className="text-ink-2">
                        Create a free cloud instance and we host it, with your licence applied automatically. Or run Vantage on your own server and get its licence free or paid from the purchase page.
                    </p>
                    <div className="flex flex-wrap gap-2.5">
                        <LinkButton href="/purchase">Buy a plan</LinkButton>
                    </div>
                </div>
            ) : (
                <PageFrame
                    aside={
                        <>
                            {attention.length > 0 && (
                                <RailCard title="Needs you" count={attention.length}>
                                    <ul className="grid gap-2">
                                        {attention.map((a) => (
                                            <li key={a.id} className="flex items-center justify-between gap-2.5 text-[0.82rem] text-ink-2">
                                                <span>{a.text}</span>
                                                {a.note && <span className="font-mono text-[0.64rem] uppercase tracking-[0.08em] text-warn">{a.note}</span>}
                                            </li>
                                        ))}
                                    </ul>
                                </RailCard>
                            )}

                            <RailCard title="Your team" count={people.data?.length}>
                                <ul className="grid gap-2">
                                    {(people.data ?? []).slice(0, 5).map((p) => (
                                        <li key={p.user_id} className="flex items-center justify-between gap-2.5 text-[0.82rem] text-ink-2">
                                            <span className="truncate">{p.email}</span>
                                            <span className="shrink-0 font-mono text-[0.64rem] uppercase tracking-[0.08em] text-ink-3">{p.account_role}</span>
                                        </li>
                                    ))}
                                </ul>
                                {pending > 0 && (
                                    <p className="border-t border-rule-soft pt-2 text-[0.78rem] text-warn">
                                        {pending} {pending === 1 ? "invitation" : "invitations"} not accepted yet
                                    </p>
                                )}
                                <Link href="/users" className="text-[0.82rem] font-semibold text-accent underline">
                                    Manage people
                                </Link>
                            </RailCard>

                            {/*
                             * Account-level facts only. Tier, limits and renewal date
                             * belong to a licence, and a licence belongs to one
                             * instance an account holding a Free cloud instance and
                             * a Professional self-hosted one has no single plan.
                             */}
                            <RailCard title="Account">
                                <RailFacts
                                    rows={[
                                        { label: "Billing contact", value: data.account.billing_email },
                                        { label: "Status", value: data.account.status },
                                        {
                                            label: "Customer since",
                                            value: formatDate(data.account.created_at),
                                        },
                                    ]}
                                />
                                <Link href="/billing" className="text-[0.82rem] font-semibold text-accent underline">
                                    Billing history
                                </Link>
                            </RailCard>

                            <RailCard title="Running Vantage yourself?">
                                <p className="text-[0.82rem] text-ink-2">Get a licence for your own install free or paid from the purchase page. It keeps its own users.</p>
                                <Link href="/purchase" className="text-[0.82rem] font-semibold text-accent underline">
                                    Get a licence
                                </Link>
                            </RailCard>
                        </>
                    }
                >
                    {live.map((i, n) => {
                        const lic = byInstance.get(i.instance_id);
                        const state = licenceState(lic?.expires_at, Boolean(lic));
                        return (
                            <InstanceRecord
                                key={i.instance_id}
                                instance={i}
                                license={lic}
                                // Open when it is the only one, or when it is the
                                // first thing that needs a decision. A saved toggle
                                // beats this from then on.
                                defaultOpen={live.length === 1 || (state !== "valid" && attention[0]?.id === i.instance_id) || (attention.length === 0 && n === 0)}
                            />
                        );
                    })}
                </PageFrame>
            )}
        </div>
    );
}
