"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { ApiError, api, type InstanceRole } from "@/lib/api";
import { useSession } from "@/lib/session";
import { Button } from "@/components/Button";

const ROLES: InstanceRole[] = ["owner", "admin", "member"];

/*
 * Absent entirely for self-hosted instances the backend refuses those, and a
 * panel that renders controls the server will reject is a panel that lies.
 */
export function MembersPanel({ instanceId }: { instanceId: string }) {
    const qc = useQueryClient();
    const { session } = useSession();
    const [selected, setSelected] = useState("");
    const [role, setRole] = useState<InstanceRole>("member");
    const [error, setError] = useState<string | null>(null);

    const members = useQuery({
        queryKey: ["members", instanceId],
        queryFn: () => api.members(instanceId),
    });
    const people = useQuery({ queryKey: ["account-users"], queryFn: api.accountUsers });

    const refresh = () => qc.invalidateQueries({ queryKey: ["members", instanceId] });
    const fail = (e: unknown) => setError(e instanceof ApiError ? e.message : "Something went wrong. Try again.");

    const grant = useMutation({
        mutationFn: () => api.grantMember(instanceId, selected, role),
        onSuccess: () => {
            setSelected("");
            setRole("member");
            refresh();
        },
        onError: fail,
    });
    const changeRole = useMutation({
        mutationFn: (v: { uid: string; role: InstanceRole }) => api.setMemberRole(instanceId, v.uid, v.role),
        onSuccess: refresh,
        onError: fail,
    });
    const revoke = useMutation({
        mutationFn: (uid: string) => api.revokeMember(instanceId, uid),
        onSuccess: refresh,
        onError: fail,
    });

    const myRole = session?.account_role;
    const canManage = myRole === "owner" || myRole === "admin";

    const granted = new Set((members.data ?? []).map((m) => m.customer_user_id));
    const candidates = (people.data ?? []).filter((p) => !granted.has(p.user_id) && p.verified_at);
    const pending = (people.data ?? []).filter((p) => !p.verified_at).length;

    return (
        <section className="grid gap-4 rounded border border-rule bg-panel p-5">
            <div className="grid gap-1">
                <h2 className="text-xl">Who can sign in</h2>
                <p className="text-[0.82rem] text-ink-2">Each person here has a real user inside this instance and signs in with their Vantage HQ password.</p>
            </div>

            {error && <p className="text-[0.9rem] text-expired">{error}</p>}

            <ul className="grid gap-2">
                {(members.data ?? []).map((m) => (
                    <li key={m.member_id} className="flex flex-wrap items-center justify-between gap-3 border-b border-rule-soft pb-2">
                        <span>{m.email}</span>
                        <span className="flex items-center gap-3">
                            {canManage ? (
                                <select
                                    value={m.role}
                                    onChange={(e) =>
                                        changeRole.mutate({
                                            uid: m.customer_user_id,
                                            role: e.target.value as InstanceRole,
                                        })
                                    }
                                    className="rounded border border-rule bg-panel-2 px-2 py-1 font-mono text-[0.82rem] text-ink"
                                >
                                    {ROLES.map((r) => (
                                        <option key={r} value={r}>
                                            {r}
                                        </option>
                                    ))}
                                </select>
                            ) : (
                                <span className="font-mono text-[0.82rem]">{m.role}</span>
                            )}
                            {canManage && (
                                <button
                                    type="button"
                                    className="text-[0.82rem] font-semibold text-expired underline"
                                    onClick={() => {
                                        if (confirm(`Remove ${m.email} from this instance?`)) revoke.mutate(m.customer_user_id);
                                    }}
                                >
                                    Remove
                                </button>
                            )}
                        </span>
                    </li>
                ))}
                {members.data?.length === 0 && <li className="text-ink-2">Nobody has been added yet.</li>}
            </ul>

            {canManage && (
                <form
                    className="flex flex-wrap items-end gap-3"
                    onSubmit={(e) => {
                        e.preventDefault();
                        setError(null);
                        if (selected) grant.mutate();
                    }}
                >
                    <label className="grid gap-1.5">
                        <span className="font-mono text-[0.72rem] uppercase tracking-[0.1em] text-ink-3">Add someone</span>
                        <select value={selected} onChange={(e) => setSelected(e.target.value)} className="rounded border border-rule bg-panel-2 px-2.5 py-2 font-mono text-ink">
                            <option value="">Choose a person…</option>
                            {candidates.map((p) => (
                                <option key={p.user_id} value={p.user_id}>
                                    {p.email}
                                </option>
                            ))}
                        </select>
                    </label>
                    <label className="grid gap-1.5">
                        <span className="font-mono text-[0.72rem] uppercase tracking-[0.1em] text-ink-3">Role here</span>
                        <select value={role} onChange={(e) => setRole(e.target.value as InstanceRole)} className="rounded border border-rule bg-panel-2 px-2.5 py-2 font-mono text-ink">
                            {ROLES.map((r) => (
                                <option key={r} value={r}>
                                    {r}
                                </option>
                            ))}
                        </select>
                    </label>
                    <Button type="submit" disabled={!selected || grant.isPending}>
                        {grant.isPending ? "Adding…" : "Add"}
                    </Button>
                </form>
            )}

            {canManage && pending > 0 && (
                <p className="text-[0.82rem] text-ink-3">
                    {pending} invited {pending === 1 ? "person has" : "people have"} not accepted yet and cannot be added until they do.
                </p>
            )}
        </section>
    );
}
