"use client";

import { useState, useEffect, useCallback } from "react";
import { useTranslations } from "next-intl";
import { Card } from "@/components/ui/card";

interface Assignment {
  userId: string;
  displayName: string;
  email: string;
  roles: string[];
  assignedAt: string;
  assignedBy: string;
  orphan: boolean;
}

interface OrgMember {
  userId: string;
  email: string;
  displayName: string;
  roles: string[];
}

interface Props {
  tenantName: string;
  /**
   * When false, the panel renders read-only — assignments are visible
   * but the add-user form and remove ✕ buttons are hidden. Pass
   * `canEdit` from the parent server component (= canMutate(user)).
   */
  canEdit: boolean;
}

/**
 * AssignedUsersPanel — manages the tenant_user_assignments rows for
 * one tenant. Owner sees:
 *   - List of currently-assigned users with name, email, role, and
 *     an "X" button to revoke.
 *   - Dropdown of org members not yet assigned + "Assign" button.
 *
 * `user`-role members see the panel read-only (canEdit=false): they
 * see who else has access to the tenant they're working with, but
 * can't change anything.
 */
export function AssignedUsersPanel({ tenantName, canEdit }: Props) {
  const t = useTranslations("assignments");
  const [assignments, setAssignments] = useState<Assignment[] | null>(null);
  const [members, setMembers] = useState<OrgMember[] | null>(null);
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);
  const [pickedUserId, setPickedUserId] = useState("");

  const refresh = useCallback(async () => {
    setError("");
    try {
      const [aRes, mRes] = await Promise.all([
        fetch(`/api/tenants/${tenantName}/assignments`),
        canEdit
          ? fetch(`/api/team`)
          : Promise.resolve(null),
      ]);
      if (!aRes.ok) throw new Error("Failed to load assignments");
      const aData = await aRes.json();
      setAssignments(aData.assignments ?? []);

      if (mRes && mRes.ok) {
        const mData = await mRes.json();
        setMembers(mData.members ?? []);
      }
    } catch (err: any) {
      setError(err.message);
    }
  }, [tenantName, canEdit]);

  useEffect(() => {
    refresh();
  }, [refresh]);

  async function handleAssign() {
    if (!pickedUserId || busy) return;
    setBusy(true);
    setError("");
    try {
      const res = await fetch(`/api/tenants/${tenantName}/assignments`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId: pickedUserId }),
      });
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || "Assign failed");
      }
      setPickedUserId("");
      await refresh();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  }

  async function handleRevoke(userId: string) {
    if (busy) return;
    setBusy(true);
    setError("");
    try {
      const res = await fetch(
        `/api/tenants/${tenantName}/assignments/${encodeURIComponent(userId)}`,
        { method: "DELETE" }
      );
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || "Revoke failed");
      }
      await refresh();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  }

  if (assignments === null) {
    return (
      <Card>
        <div className="text-xs text-text-muted">{t("loading")}</div>
      </Card>
    );
  }

  // Compute candidates for the assign dropdown: members of the org
  // who hold the `user` role (not owners — they have implicit access)
  // and aren't already assigned.
  const assignedIds = new Set(assignments.map((a) => a.userId));
  const candidates = (members ?? []).filter(
    (m) =>
      !assignedIds.has(m.userId) &&
      m.roles.includes("user") &&
      !m.roles.includes("owner")
  );

  return (
    <Card>
      {error && (
        <div className="text-xs text-red-400 bg-red-400/10 border border-red-400/20 rounded-lg px-3 py-2 mb-3">
          {error}
          <button
            onClick={() => setError("")}
            className="ml-2 text-red-300 hover:text-red-200"
          >
            ✕
          </button>
        </div>
      )}

      {assignments.length === 0 ? (
        <p className="text-sm text-text-secondary text-center py-3">
          {t("noneAssigned")}
        </p>
      ) : (
        <ul className="divide-y divide-border -mx-2">
          {assignments.map((a) => (
            <li
              key={a.userId}
              className="px-2 py-2 flex items-center justify-between gap-3"
            >
              <div className="min-w-0">
                <div className="text-sm font-medium text-text-primary truncate">
                  {a.orphan ? (
                    <span className="text-text-muted italic">
                      {a.displayName}
                    </span>
                  ) : (
                    a.displayName
                  )}
                </div>
                {a.email && (
                  <div className="text-xs text-text-muted truncate font-mono">
                    {a.email}
                  </div>
                )}
              </div>
              {canEdit && (
                <button
                  onClick={() => handleRevoke(a.userId)}
                  disabled={busy}
                  className="text-text-muted/60 hover:text-red-400 transition-colors disabled:opacity-50 text-sm px-2"
                  title={t("revoke")}
                >
                  ✕
                </button>
              )}
            </li>
          ))}
        </ul>
      )}

      {canEdit && (
        <div className="mt-4 pt-4 border-t border-border">
          {candidates.length === 0 ? (
            <p className="text-xs text-text-muted text-center py-2">
              {t("noCandidates")}
            </p>
          ) : (
            <div className="flex gap-2">
              <select
                value={pickedUserId}
                onChange={(e) => setPickedUserId(e.target.value)}
                className="flex-1 px-3 py-2 bg-surface-2 border border-border rounded-lg text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-accent focus:border-accent transition-colors"
              >
                <option value="">{t("pickUser")}</option>
                {candidates.map((m) => (
                  <option key={m.userId} value={m.userId}>
                    {m.displayName || m.email}
                  </option>
                ))}
              </select>
              <button
                onClick={handleAssign}
                disabled={busy || !pickedUserId}
                className="px-4 py-2 text-sm font-medium bg-accent text-white rounded-lg hover:bg-accent-dim transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {busy ? "…" : t("assign")}
              </button>
            </div>
          )}
        </div>
      )}
    </Card>
  );
}
