import { Popover } from '@/Components/ui';
import { cn } from '@/lib/cn';
import type { SharedProps } from '@/types/inertia';
import { Link, router, usePage } from '@inertiajs/react';
import {
    Activity as ActivityIcon,
    Check,
    ChevronDown,
    Mail,
    Settings2,
    Users,
} from 'lucide-react';
import type { JSX } from 'react';

/**
 * Workspace roles. `owner`/`admin` are the privileged tones (accent/brand,
 * Δ11); `editor`/`viewer` render neutral. The string is intentionally
 * widened to `string` on the wire shape since the backend may grow roles —
 * unknown roles fall through to the neutral branch.
 */
export type WorkspaceRole = 'owner' | 'admin' | 'editor' | 'viewer';

type WorkspaceMembership = {
    id: number;
    name: string;
    role: string;
    personal: boolean;
};

type ActiveWorkspace = {
    id: number;
    name: string;
    role: WorkspaceRole;
    personal: boolean;
    /** Seat window for the active workspace (P5 — owner-downgrade banner).
     *  `limit: null` = unlimited (Scale / no cap). `seat_over_limit` is true
     *  when the plan can no longer cover the edit-capable members. */
    seat?: { used: number; limit: number | null };
    seat_over_limit?: boolean;
    /** True when a higher-tier active plan exists above the workspace's
     *  current plan — drives the AppNav "Upgrade" button. */
    can_upgrade?: boolean;
};

/**
 * Shared `workspaces` prop. SaaS app-surfaces only; `null` in self-hosted
 * (the switcher renders nothing there). Shipped by `HandleInertiaRequests`
 * — see `team-workspaces-plan.md` §Switcher UX. Read directly off the page
 * props each render (Δ10) — never seeded into local `useState`.
 */
export type WorkspacesProp = {
    active: ActiveWorkspace;
    memberships: WorkspaceMembership[];
    pending_invites_count: number;
} | null;

function roleLabel(role: string): string {
    switch (role) {
        case 'owner':
            return 'Owner';
        case 'admin':
            return 'Admin';
        case 'editor':
            return 'Editor';
        case 'viewer':
            return 'Viewer';
        default:
            return role.charAt(0).toUpperCase() + role.slice(1);
    }
}

/** Owner/Admin are privileged → accent/brand tone (Δ11). Editor/Viewer are
 *  neutral so the badge doesn't shout for the common case. */
function roleBadgeClasses(role: string): string {
    return role === 'owner' || role === 'admin'
        ? 'border-accent/30 bg-accent/10 text-accent'
        : 'border-border bg-muted text-muted-foreground';
}

export default function WorkspaceSwitcher(): JSX.Element | null {
    // Δ10 — read the prop directly each render. AppNav chrome is always
    // mounted, so partial reloads refresh this prop without a remount; seeding
    // local state from it once would go stale (the toolbar sync-toggle bug).
    const { workspaces } = usePage<SharedProps & { workspaces: WorkspacesProp }>()
        .props;

    // Self-hosted (prop null) or a not-yet-shipped prop → render nothing.
    if (!workspaces) return null;

    const { active, memberships, pending_invites_count } = workspaces;

    const switchTo = (tenant: number) => {
        if (tenant === active.id) return;
        router.post(
            '/workspace/switch',
            { tenant },
            {
                preserveScroll: false,
                preserveState: false,
            },
        );
    };

    const canManage = active.role === 'owner' || active.role === 'admin';

    return (
        <div className="flex items-center gap-1">
        <Popover
            align="start"
            trigger={({ open, toggle }) => (
                <button
                    type="button"
                    onClick={toggle}
                    data-testid="workspace-switcher"
                    aria-expanded={open}
                    aria-label="Switch workspace"
                    className={cn(
                        'inline-flex h-8 max-w-[130px] items-center gap-1.5 rounded-md border border-border px-2 text-[13px] font-medium transition-colors sm:max-w-[200px]',
                        open
                            ? 'bg-muted text-foreground'
                            : 'bg-card text-foreground hover:bg-muted/60',
                    )}
                >
                    <span className="truncate">{active.name}</span>
                    <span
                        className={cn(
                            'shrink-0 rounded-sm border px-1 text-[9px] font-medium uppercase tracking-wider',
                            roleBadgeClasses(active.role),
                        )}
                        data-testid="workspace-switcher-active-role"
                    >
                        {roleLabel(active.role)}
                    </span>
                    {pending_invites_count > 0 && (
                        <span
                            className="flex h-4 min-w-4 shrink-0 items-center justify-center rounded-full bg-accent px-1 text-[9px] font-semibold text-accent-foreground"
                            data-testid="workspace-switcher-pending-badge"
                            aria-label={`${pending_invites_count} pending ${pending_invites_count === 1 ? 'invite' : 'invites'}`}
                        >
                            {pending_invites_count}
                        </span>
                    )}
                    <ChevronDown
                        className="h-3 w-3 shrink-0 text-muted-foreground"
                        strokeWidth={2}
                    />
                </button>
            )}
        >
            <div className="flex min-w-[260px] flex-col">
                <div className="px-2 pb-1 pt-1 text-[9px] font-medium uppercase tracking-wider text-muted-foreground/70">
                    Workspaces
                </div>
                <div className="flex flex-col gap-0.5">
                    {memberships.map((m) => {
                        const isActive = m.id === active.id;
                        return (
                            <button
                                key={m.id}
                                type="button"
                                onClick={() => switchTo(m.id)}
                                data-testid={`workspace-option-${m.id}`}
                                data-active={isActive ? 'true' : undefined}
                                className={cn(
                                    'flex items-center justify-between gap-3 rounded-md px-2 py-1.5 text-left text-xs transition-colors',
                                    isActive
                                        ? 'bg-accent/10 text-accent'
                                        : 'text-foreground hover:bg-muted',
                                )}
                            >
                                <span className="flex min-w-0 flex-col gap-0.5">
                                    <span className="truncate">{m.name}</span>
                                    <span className="truncate text-[10px] font-normal text-muted-foreground/80">
                                        {/* "Personal" only for YOUR OWN personal
                                            workspace (you own it). A workspace
                                            you were invited into — even if it's
                                            the inviter's personal one — just
                                            shows your role. */}
                                        {m.personal && m.role === 'owner'
                                            ? `Personal · ${roleLabel(m.role)}`
                                            : roleLabel(m.role)}
                                    </span>
                                </span>
                                <span className="flex h-4 w-4 items-center justify-center text-muted-foreground">
                                    {isActive ? (
                                        <Check
                                            className="h-3.5 w-3.5 text-accent"
                                            strokeWidth={2.5}
                                        />
                                    ) : null}
                                </span>
                            </button>
                        );
                    })}
                </div>
                {/* Quick link to the members page — always present so the
                    switcher serves as a single entry-point for workspace
                    management without having to open the gear menu. */}
                <div className="mt-1 border-t border-border pt-1">
                    <Link
                        href="/workspace/members"
                        data-testid="workspace-switcher-manage"
                        className="flex items-center gap-2 rounded-md px-2 py-1.5 text-xs text-foreground transition-colors hover:bg-muted"
                    >
                        <Users className="h-3.5 w-3.5 text-muted-foreground" strokeWidth={2} />
                        <span>{canManage ? 'Members' : 'Your membership'}</span>
                    </Link>
                </div>

                {/* Pending-invite prompt stays here (it's invite-related, only
                    shows when there's one). */}
                {pending_invites_count > 0 && (
                    <div className="mt-1 border-t border-border pt-1">
                        <Link
                            href="/workspace/invitations"
                            data-testid="workspace-switcher-invitations"
                            className="flex items-center justify-between gap-2 rounded-md px-2 py-1.5 text-xs font-medium text-accent transition-colors hover:bg-accent/10"
                        >
                            <span className="flex items-center gap-2">
                                <Mail className="h-3.5 w-3.5" strokeWidth={2} />
                                <span>
                                    Pending{' '}
                                    {pending_invites_count === 1
                                        ? 'invitation'
                                        : 'invitations'}
                                </span>
                            </span>
                            <span
                                className="flex h-4 min-w-4 items-center justify-center rounded-full bg-accent px-1 text-[9px] font-semibold text-accent-foreground"
                                aria-hidden
                            >
                                {pending_invites_count}
                            </span>
                        </Link>
                    </div>
                )}
            </div>
        </Popover>

        {/* Workspace menu — management actions, separated from the selection
            switcher so the dropdown above does one thing (switch workspace).
            Members is visible to everyone (managers manage; others see a self-
            view); Activity is owner/admin only. */}
        <Popover
            align="end"
            trigger={({ open, toggle }) => (
                <button
                    type="button"
                    onClick={toggle}
                    data-testid="workspace-menu"
                    aria-expanded={open}
                    aria-label="Workspace menu"
                    className={cn(
                        'inline-flex h-8 w-8 items-center justify-center rounded-md border border-border transition-colors',
                        open
                            ? 'bg-muted text-foreground'
                            : 'bg-card text-muted-foreground hover:bg-muted/60 hover:text-foreground',
                    )}
                >
                    <Settings2 className="h-4 w-4" strokeWidth={2} />
                </button>
            )}
        >
            <div className="flex min-w-[180px] flex-col">
                <Link
                    href="/workspace/members"
                    data-testid="workspace-menu-members"
                    className="flex items-center gap-2 rounded-md px-2 py-1.5 text-xs text-foreground transition-colors hover:bg-muted"
                >
                    <Users
                        className="h-3.5 w-3.5 text-muted-foreground"
                        strokeWidth={2}
                    />
                    <span>{canManage ? 'Members' : 'Your membership'}</span>
                </Link>
                {canManage && (
                    <Link
                        href="/workspace/activity"
                        data-testid="workspace-menu-activity"
                        className="flex items-center gap-2 rounded-md px-2 py-1.5 text-xs text-foreground transition-colors hover:bg-muted"
                    >
                        <ActivityIcon
                            className="h-3.5 w-3.5 text-muted-foreground"
                            strokeWidth={2}
                        />
                        <span>Activity</span>
                    </Link>
                )}
            </div>
        </Popover>
        </div>
    );
}
