"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { api, ApiError, forceLogin } from "../../lib/api";
import { createPlatformAdapter } from "../../platform/adapter";

interface WorkspaceRow {
  id: string;
  name: string;
  slug: string;
  role: string;
}

interface PendingInvite {
  id: string;
  workspaceId: string;
  workspaceName: string;
  workspaceSlug: string;
  role: string;
  invitedByName: string | null;
  expiresAt: string;
  createdAt: string;
}

const platform = createPlatformAdapter();

const ICON_COLORS = [
  { bg: "#1a73e8", fg: "#fff" },
  { bg: "#23c063", fg: "#fff" },
  { bg: "#e5326b", fg: "#fff" },
  { bg: "#e0563b", fg: "#fff" },
  { bg: "#f59e0b", fg: "#fff" },
  { bg: "#db2777", fg: "#fff" },
  { bg: "#0d9488", fg: "#fff" },
  { bg: "#4f46e5", fg: "#fff" },
];

function slugify(value: string) {
  return value
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 64);
}

export default function WorkspacesPage() {
  const router = useRouter();
  const [workspaces, setWorkspaces] = useState<WorkspaceRow[] | null>(null);
  const [pending, setPending] = useState<PendingInvite[]>([]);
  const [query, setQuery] = useState("");
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [showCreate, setShowCreate] = useState(false);
  const [name, setName] = useState("");
  const [slug, setSlug] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const [inviteBusy, setInviteBusy] = useState<string | null>(null);

  async function load() {
    try {
      const res = await api.myWorkspaces();
      const rows = res.workspaces as WorkspaceRow[];
      setWorkspaces(rows);
      setSelectedId((current) => current ?? rows[0]?.id ?? null);
    } catch (err) {
      if (err instanceof ApiError && err.status === 401) {
        await forceLogin(router);
        return;
      }
      setError(String(err));
    }
  }

  async function loadPending() {
    try {
      const res = await api.pendingInvites();
      setPending(res.invites);
      if (res.invites.length > 0) {
        const newest = res.invites[0]!;
        const seenKey = `voxi:invite-notified:${newest.id}`;
        if (typeof sessionStorage !== "undefined" && !sessionStorage.getItem(seenKey)) {
          sessionStorage.setItem(seenKey, "1");
          await platform.notifications.notify(
            `Join ${newest.workspaceName}`,
            newest.invitedByName
              ? `${newest.invitedByName} invited you to a workspace`
              : "You have a workspace invite waiting",
          );
        }
        await platform.badge.setBadge(res.invites.length);
      } else {
        await platform.badge.clearBadge();
      }
    } catch {
      // Pending invites are best-effort on this page.
    }
  }

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

  const filtered = useMemo(() => {
    if (!workspaces) return [];
    const q = query.trim().toLowerCase();
    if (!q) return workspaces;
    return workspaces.filter((ws) => ws.name.toLowerCase().includes(q) || ws.slug.toLowerCase().includes(q));
  }, [workspaces, query]);

  async function createWorkspace(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setBusy(true);
    try {
      const created = (await api.createWorkspace({ name, slug: slug || slugify(name) })) as { id?: string };
      setName("");
      setSlug("");
      setShowCreate(false);
      await load();
      if (created?.id) router.push(`/workspace?id=${created.id}`);
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setBusy(false);
    }
  }

  async function acceptInvite(inviteId: string, workspaceId: string) {
    setInviteBusy(inviteId);
    setError(null);
    try {
      await api.acceptInviteById(inviteId);
      await load();
      await loadPending();
      router.push(`/workspace?id=${workspaceId}`);
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setInviteBusy(null);
    }
  }

  async function declineInvite(inviteId: string) {
    setInviteBusy(inviteId);
    setError(null);
    try {
      await api.declineInvite(inviteId);
      await loadPending();
    } catch (err) {
      setError(err instanceof ApiError ? JSON.stringify(err.body) : String(err));
    } finally {
      setInviteBusy(null);
    }
  }

  return (
    <main className="ws-picker">
      <div className="ws-picker-inner">
        <header className="ws-picker-head">
          <div>
            <p className="ws-picker-greet">
              Welcome back <span>👋</span>
            </p>
            <h1 className="ws-picker-title">Choose a workspace</h1>
            <p className="ws-picker-sub">Jump back into your conversations and projects.</p>
          </div>
          <button className="ws-picker-create-btn" type="button" onClick={() => setShowCreate((v) => !v)}>
            <span aria-hidden="true">+</span>
            Create new workspace
          </button>
        </header>

        {pending.length > 0 && (
          <section className="ws-invite-banner" aria-label="Pending workspace invites">
            <div className="ws-invite-banner-head">
              <h2>Workspace invites</h2>
              <p>Accept to join. You will not be added until you confirm.</p>
            </div>
            <div className="ws-invite-list">
              {pending.map((invite) => (
                <article className="ws-invite-card" key={invite.id}>
                  <div>
                    <strong>{invite.workspaceName}</strong>
                    <p>
                      {invite.invitedByName ? `${invite.invitedByName} invited you` : "You were invited"} · /{invite.workspaceSlug} · {invite.role}
                    </p>
                  </div>
                  <div className="ws-invite-actions">
                    <button
                      className="screen-btn"
                      type="button"
                      disabled={inviteBusy === invite.id}
                      onClick={() => declineInvite(invite.id)}
                    >
                      Decline
                    </button>
                    <button
                      className="screen-btn primary"
                      type="button"
                      disabled={inviteBusy === invite.id}
                      onClick={() => acceptInvite(invite.id, invite.workspaceId)}
                    >
                      {inviteBusy === invite.id ? "Working…" : "Accept"}
                    </button>
                  </div>
                </article>
              ))}
            </div>
          </section>
        )}

        <div className="ws-picker-toolbar">
          <label className="ws-picker-search">
            <span className="ws-picker-search-icon" aria-hidden="true">
              ⌕
            </span>
            <input
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search workspaces..."
              aria-label="Search workspaces"
            />
          </label>
          <button className="ws-picker-sort" type="button" title="Sort is visual for now">
            <span aria-hidden="true">◷</span>
            Last active
            <span aria-hidden="true">⌄</span>
          </button>
        </div>

        {workspaces === null && <p className="muted">Loading workspaces...</p>}

        {workspaces && filtered.length === 0 && pending.length === 0 && (
          <div className="empty-state">No workspaces match your search.</div>
        )}

        <div className="ws-picker-grid">
          {filtered.map((ws, index) => {
            const color = ICON_COLORS[index % ICON_COLORS.length]!;
            const selected = ws.id === selectedId;
            return (
              <Link
                key={ws.id}
                href={`/workspace?id=${ws.id}`}
                className={selected ? "ws-card selected" : "ws-card"}
                onMouseEnter={() => setSelectedId(ws.id)}
                onFocus={() => setSelectedId(ws.id)}
              >
                <div className="ws-card-top">
                  <span className="ws-card-icon" style={{ background: color.bg, color: color.fg }}>
                    {ws.name.slice(0, 1).toUpperCase()}
                  </span>
                  <span className="ws-card-more" aria-hidden="true">
                    ⋮
                  </span>
                </div>
                <span className="ws-card-status" aria-hidden="true" />
                <div className="ws-card-title-row">
                  <h2 className="ws-card-title">{ws.name}</h2>
                  {(ws.role === "owner" || ws.role === "admin") && (
                    <span className="ws-card-badge">{ws.role === "owner" ? "Owner" : "Admin"}</span>
                  )}
                </div>
                <p className="ws-card-meta">/{ws.slug}</p>
                <p className="ws-card-active">Role · {ws.role}</p>
                {selected && (
                  <span className="ws-card-check" aria-hidden="true">
                    ✓
                  </span>
                )}
              </Link>
            );
          })}
        </div>

        {!showCreate ? (
          <button className="ws-picker-create-panel" type="button" onClick={() => setShowCreate(true)}>
            <span className="ws-picker-create-orb" aria-hidden="true">
              +
            </span>
            <strong>Create a new workspace</strong>
            <span>Start a new workspace and invite your team</span>
          </button>
        ) : (
          <section className="ws-picker-create-form">
            <h2>Create a new workspace</h2>
            <p className="muted">Start a new workspace and invite your team.</p>
            <form className="form-stack" onSubmit={createWorkspace}>
              <input
                className="field"
                placeholder="Workspace name"
                aria-label="Workspace name"
                value={name}
                onChange={(e) => {
                  setName(e.target.value);
                  if (!slug || slug === slugify(name)) setSlug(slugify(e.target.value));
                }}
                required
              />
              <input
                className="field"
                placeholder="slug (a-z0-9-)"
                aria-label="Workspace slug"
                value={slug}
                onChange={(e) => setSlug(e.target.value)}
                pattern="[a-z0-9-]{2,64}"
                required
              />
              <div className="ws-picker-form-actions">
                <button className="ws-picker-cancel" type="button" onClick={() => setShowCreate(false)}>
                  Cancel
                </button>
                <button className="button-primary" type="submit" disabled={busy}>
                  {busy ? "Creating..." : "Create workspace"}
                </button>
              </div>
            </form>
          </section>
        )}

        {error && <p className="error-text">{error}</p>}
      </div>
    </main>
  );
}
