"use client";

import Link from "next/link";
import { Suspense, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { AppShell, ScreenHeader, useWorkspaceIdParam } from "../../components/AppShell";
import { api, ApiError, forceLogin } from "../../lib/api";
import { avatarColor, initials } from "../../lib/avatar";

interface AdminOverview {
  workspace: { id: string; name: string; slug: string; retentionDays: number | null };
  members: Array<{ member: { role: string; deactivatedAt?: string | null; userId: string }; user: { id: string; name: string; email: string } }>;
  invites: Array<{ id: string; email: string | null; role: string; expiresAt: string; maxUses: number }>;
  channels: Array<{ id: string; name: string | null; type: string }>;
}

function AdminView() {
  const router = useRouter();
  const workspaceId = useWorkspaceIdParam();
  const [data, setData] = useState<AdminOverview | null>(null);
  const [inviteEmail, setInviteEmail] = useState("");
  const [inviteToken, setInviteToken] = useState<string | null>(null);
  const [wsName, setWsName] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  async function load() {
    if (!workspaceId) return;
    try {
      const overview = (await api.adminOverview(workspaceId)) as AdminOverview;
      setData(overview);
      setWsName(overview.workspace.name);
    } catch (err) {
      if (err instanceof ApiError && err.status === 401) void forceLogin(router);
      else if (err instanceof ApiError && err.status === 403) setError("Admin access required.");
      else setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    }
  }

  useEffect(() => {
    load();
  }, [workspaceId]);

  async function createInvite(e: React.FormEvent) {
    e.preventDefault();
    if (!workspaceId) return;
    setBusy(true);
    setError(null);
    try {
      const invite = (await api.createInvite(workspaceId, {
        email: inviteEmail.trim(),
        role: "member",
      })) as { token?: string; userExists?: boolean; notified?: boolean };
      setInviteToken(invite.token ?? null);
      setInviteEmail("");
      await load();
      if (invite.userExists && invite.notified) {
        setError(null);
      }
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setBusy(false);
    }
  }

  async function saveSettings(e: React.FormEvent) {
    e.preventDefault();
    if (!workspaceId || !wsName.trim()) return;
    setBusy(true);
    setError(null);
    try {
      await api.updateWorkspaceSettings(workspaceId, { name: wsName.trim() });
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setBusy(false);
    }
  }

  async function changeRole(userId: string, role: string) {
    if (!workspaceId) return;
    setBusy(true);
    setError(null);
    try {
      await api.changeMemberRole(workspaceId, userId, role);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setBusy(false);
    }
  }

  async function toggleActive(userId: string, deactivated: boolean) {
    if (!workspaceId) return;
    setBusy(true);
    setError(null);
    try {
      if (deactivated) await api.reactivateMember(workspaceId, userId);
      else await api.deactivateMember(workspaceId, userId);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setBusy(false);
    }
  }

  return (
    <AppShell active="home" title="Admin" subtitle="Workspace console">
      <ScreenHeader
        title="Admin"
        subtitle={data ? `${data.workspace.name} · /${data.workspace.slug}` : "Loading…"}
        actions={<Link className="screen-btn" href={`/settings?workspaceId=${workspaceId}`}>Settings</Link>}
      />
      <div className="screen-body">
        {error && <p className="error-text">{error}</p>}
        {!data && !error && <div className="empty-state">Loading admin overview…</div>}
        {data && (
          <div className="screen-grid">
            <section className="screen-card">
              <h2>Workspace settings</h2>
              <form className="form-stack" onSubmit={saveSettings}>
                <label>
                  Name
                  <input value={wsName} onChange={(e) => setWsName(e.target.value)} required />
                </label>
                <button className="screen-btn primary" type="submit" disabled={busy}>Save</button>
              </form>
            </section>

            <section className="screen-card">
              <h2>Invite people</h2>
              <form className="form-stack" onSubmit={createInvite}>
                <input
                  type="email"
                  value={inviteEmail}
                  onChange={(e) => setInviteEmail(e.target.value)}
                  placeholder="email@company.com"
                  required
                />
                <button className="screen-btn primary" type="submit" disabled={busy}>Create invite</button>
              </form>
              {inviteToken && (
                <p className="invite-token">
                  Invite token (copy once): <code>{inviteToken}</code>
                  <br />
                  Accept at <Link href={`/invite?workspaceId=${workspaceId}&token=${inviteToken}`}>/invite</Link>
                </p>
              )}
              {!inviteToken && (
                <p className="muted" style={{ marginTop: 8 }}>
                  Existing accounts get an in-app notification and must accept from their workspace list.
                </p>
              )}
              <div className="screen-list" style={{ marginTop: 12 }}>
                {data.invites.map((invite) => (
                  <div className="screen-list-item" key={invite.id}>
                    <span>{invite.email ?? "Open invite"} · {invite.role}</span>
                    <span className="muted">expires {new Date(invite.expiresAt).toLocaleDateString()}</span>
                  </div>
                ))}
                {data.invites.length === 0 && <div className="empty-state">No pending invites.</div>}
              </div>
            </section>

            <section className="screen-card wide">
              <h2>Members ({data.members.length})</h2>
              <div className="admin-table">
                {data.members.map((row) => {
                  const color = avatarColor(row.user.id);
                  const deactivated = Boolean(row.member.deactivatedAt);
                  return (
                    <div className="admin-row" key={row.user.id}>
                      <span className="list-row-avatar" style={{ background: color.bg, color: color.fg }}>
                        {initials(row.user.name)}
                      </span>
                      <div className="admin-row-main">
                        <strong>{row.user.name}</strong>
                        <span>{row.user.email}</span>
                      </div>
                      <select
                        value={row.member.role}
                        disabled={busy || row.member.role === "owner"}
                        onChange={(e) => changeRole(row.user.id, e.target.value)}
                        aria-label={`Role for ${row.user.name}`}
                      >
                        <option value="owner">owner</option>
                        <option value="admin">admin</option>
                        <option value="member">member</option>
                        <option value="multi_channel_guest">multi-channel guest</option>
                        <option value="single_channel_guest">single-channel guest</option>
                      </select>
                      <button
                        className="screen-btn"
                        type="button"
                        disabled={busy || row.member.role === "owner"}
                        onClick={() => toggleActive(row.user.id, deactivated)}
                      >
                        {deactivated ? "Reactivate" : "Deactivate"}
                      </button>
                    </div>
                  );
                })}
              </div>
            </section>

            <section className="screen-card">
              <h2>Channels ({data.channels.length})</h2>
              <div className="screen-list">
                {data.channels.map((ch) => (
                  <Link
                    key={ch.id}
                    className="screen-list-item"
                    href={`/channel?workspaceId=${workspaceId}&channelId=${ch.id}`}
                  >
                    <span className="hash">#</span>
                    <span>{ch.name ?? ch.id}</span>
                    <span className="muted">{ch.type}</span>
                  </Link>
                ))}
              </div>
            </section>
          </div>
        )}
      </div>
    </AppShell>
  );
}

export default function AdminPage() {
  return (
    <Suspense fallback={<main className="page"><div className="empty-state">Loading admin…</div></main>}>
      <AdminView />
    </Suspense>
  );
}
