"use client";

import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";

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

interface Props {
  initialMembers: OrgMember[];
  currentUserId: string;
  /**
   * Whether the viewing user can change other members' roles. True only
   * for customer owners. Server enforces this independently — this prop
   * is purely UX (don't render the control if the action would 403).
   */
  canEditRoles: boolean;
}

type RoleOption = "owner" | "user";

/**
 * TeamList — renders the org's members. Refreshes after invites by
 * polling the API; the InviteForm broadcasts a `team:refresh` window
 * event after a successful invite so the list updates immediately
 * rather than waiting for the next reload.
 *
 * Slice 7 + Bug 25: owners can change other members' roles inline.
 * Clicking the "Change role" button on a row swaps the badge for a
 * dropdown + Save/Cancel pair. We deliberately don't use a modal —
 * the change is a single-field edit and the user already sees the row
 * context, so inline is faster.
 *
 * Self-row never shows the editor (server enforces too). Last-owner
 * demotion is enforced server-side; we surface the resulting 409 as a
 * row-local error rather than pre-validating client-side, because the
 * client doesn't know the org's full owner count without an extra
 * round trip.
 */
export function TeamList({
  initialMembers,
  currentUserId,
  canEditRoles,
}: Props) {
  const t = useTranslations("team");
  const [members, setMembers] = useState<OrgMember[]>(initialMembers);

  // Per-row editor state. `editingId` is the userId currently being
  // edited (only one at a time). `pendingRole` is the dropdown value.
  // `rowError` carries server-rejection messages keyed by userId.
  const [editingId, setEditingId] = useState<string | null>(null);
  const [pendingRole, setPendingRole] = useState<RoleOption>("user");
  const [submitting, setSubmitting] = useState(false);
  const [rowError, setRowError] = useState<Record<string, string>>({});

  useEffect(() => {
    function refresh() {
      fetch("/api/team")
        .then((r) => (r.ok ? r.json() : null))
        .then((data) => {
          if (data?.members) setMembers(data.members);
        })
        .catch(() => {});
    }
    window.addEventListener("team:refresh", refresh);
    return () => window.removeEventListener("team:refresh", refresh);
  }, []);

  function startEdit(m: OrgMember) {
    const current = (m.roles[0] === "owner" ? "owner" : "user") as RoleOption;
    setEditingId(m.userId);
    setPendingRole(current);
    setRowError((e) => ({ ...e, [m.userId]: "" }));
  }

  function cancelEdit() {
    setEditingId(null);
    setSubmitting(false);
  }

  async function saveEdit(m: OrgMember) {
    setSubmitting(true);
    setRowError((e) => ({ ...e, [m.userId]: "" }));
    try {
      const res = await fetch(
        `/api/team/${encodeURIComponent(m.userId)}/role`,
        {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ role: pendingRole }),
        }
      );
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || t("roleUpdateFailed"));
      }
      // Optimistic update — replace the row's roles locally rather than
      // re-fetching the whole list. The list will eventually re-fetch
      // on the next `team:refresh` event anyway.
      setMembers((prev) =>
        prev.map((x) =>
          x.userId === m.userId ? { ...x, roles: [pendingRole] } : x
        )
      );
      setEditingId(null);
    } catch (err: any) {
      setRowError((e) => ({ ...e, [m.userId]: err.message }));
    } finally {
      setSubmitting(false);
    }
  }

  if (members.length === 0) {
    return (
      <div className="text-sm text-text-secondary text-center py-6 border border-border rounded-xl bg-surface-1">
        {t("noMembers")}
      </div>
    );
  }

  return (
    <div className="bg-surface-1 border border-border rounded-xl overflow-hidden">
      <ul className="divide-y divide-border">
        {members.map((m) => {
          const isSelf = m.userId === currentUserId;
          const isEditing = editingId === m.userId;
          // Hide editor for self even when the viewer is an owner —
          // self-demotion is server-blocked and offering it as a UI
          // affordance would just produce errors.
          const showEditor = canEditRoles && !isSelf;
          const err = rowError[m.userId];

          return (
            <li
              key={m.userId}
              className="px-5 py-3 flex items-center justify-between gap-4"
            >
              <div className="min-w-0">
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-text-primary truncate">
                    {m.displayName || m.email}
                  </span>
                  {isSelf && (
                    <span className="text-[10px] uppercase tracking-wider text-accent">
                      {t("you")}
                    </span>
                  )}
                </div>
                <div className="text-xs text-text-muted truncate font-mono">
                  {m.email}
                </div>
                {err && (
                  <div className="text-xs text-red-400 mt-1">{err}</div>
                )}
              </div>

              <div className="flex items-center gap-2 shrink-0">
                {isEditing ? (
                  <>
                    <select
                      value={pendingRole}
                      onChange={(e) =>
                        setPendingRole(e.target.value as RoleOption)
                      }
                      disabled={submitting}
                      className="text-xs bg-surface-2 border border-border rounded-md px-2 py-1 text-text-primary focus:outline-none focus:ring-1 focus:ring-accent focus:border-accent"
                    >
                      <option value="user">{t("roleUser")}</option>
                      <option value="owner">{t("roleOwner")}</option>
                    </select>
                    <button
                      type="button"
                      onClick={() => saveEdit(m)}
                      disabled={submitting || !m.authorizationId}
                      className="text-xs px-2.5 py-1 rounded-md bg-accent text-white hover:bg-accent-dim transition-colors disabled:opacity-50"
                    >
                      {t("save")}
                    </button>
                    <button
                      type="button"
                      onClick={cancelEdit}
                      disabled={submitting}
                      className="text-xs px-2.5 py-1 rounded-md border border-border text-text-secondary hover:text-text-primary transition-colors"
                    >
                      {t("cancel")}
                    </button>
                  </>
                ) : (
                  <>
                    <div className="flex flex-wrap gap-1.5 justify-end">
                      {m.roles.length === 0 && (
                        <span className="text-[10px] uppercase tracking-wider text-text-muted bg-surface-3 px-2 py-0.5 rounded-full">
                          {t("noRole")}
                        </span>
                      )}
                      {m.roles.map((r) => (
                        <span
                          key={r}
                          className={`text-[10px] uppercase tracking-wider px-2 py-0.5 rounded-full ${
                            r === "owner"
                              ? "bg-accent/15 text-accent border border-accent/20"
                              : "bg-surface-3 text-text-secondary border border-border"
                          }`}
                        >
                          {r}
                        </span>
                      ))}
                    </div>
                    {showEditor && (
                      <button
                        type="button"
                        onClick={() => startEdit(m)}
                        title={t("changeRole")}
                        className="text-xs text-text-muted hover:text-text-primary px-2 py-1 rounded-md transition-colors"
                      >
                        {t("changeRole")}
                      </button>
                    )}
                  </>
                )}
              </div>
            </li>
          );
        })}
      </ul>
    </div>
  );
}
