'use client';

import type { Position, StoreMember } from '@alqove/api-client';
import { formatPrice } from '@alqove/shared';
import { useSelectedStoreId } from '@/lib/stores/store-context';
import { useStoreCapabilities } from '@/lib/store-capabilities';
import {
  useRevokeInvitation,
  useStoreInvitations,
  useStoreMembers,
  useStorePositions,
} from '@/lib/queries/use-team';
import { MemberRoleBadge } from '@/components/seller/member-role-badge';
import { InviteMemberDialog } from '@/components/seller/invite-member-dialog';
import { EditMemberDialog } from '@/components/seller/edit-member-dialog';
import { PayRateDialog } from '@/components/seller/pay-rate-dialog';

/**
 * Team roster (Port 00 §7). What's rendered is decided by the caller's
 * resolved capabilities at this store — never a role name — and the API
 * strips pay/contact fields server-side regardless, so a client bug can't
 * leak them.
 */
export function SellerTeamClient() {
  const storeId = useSelectedStoreId();
  const caps = useStoreCapabilities(storeId);

  const members = useStoreMembers(storeId);
  const positions = useStorePositions(storeId);
  const canManage = caps.can('team.manage');
  const canViewPay = caps.can('pay.view');
  const canManagePay = caps.can('pay.manage');

  const rows = members.data?.data ?? [];
  const positionList = positions.data?.data ?? [];

  return (
    <div>
      <div className="flex items-start justify-between">
        <div>
          <h1 className="text-2xl font-bold text-ink">Team</h1>
          <p className="mt-1 text-sm text-ink/60">
            Who works at your store and what they can do.
          </p>
        </div>
        {canManage && storeId && (
          <InviteMemberDialog
            storeId={storeId}
            actorRank={caps.rank}
            positions={positionList}
            trigger={
              <button
                type="button"
                data-testid="team-invite-button"
                className="rounded bg-forest px-4 py-2 text-sm font-semibold text-white hover:bg-forest/90"
              >
                Invite member
              </button>
            }
          />
        )}
      </div>

      <div className="mt-4 overflow-hidden rounded-md border border-forest/20 bg-white">
        {members.isLoading && (
          <table className="w-full text-sm" data-testid="team-loading">
            <tbody>
              {[0, 1, 2].map((i) => (
                <tr key={i} className="border-t border-forest/10 first:border-t-0">
                  <td className="px-4 py-3">
                    <div className="h-4 w-32 animate-pulse rounded bg-forest/10" />
                  </td>
                  <td className="px-4 py-3">
                    <div className="h-4 w-16 animate-pulse rounded bg-forest/10" />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
        {members.isError && (
          <div className="p-8 text-center text-sm text-terracotta" data-testid="team-error">
            Failed to load your team.
          </div>
        )}
        {!members.isLoading && !members.isError && rows.length === 0 && (
          <div className="p-8 text-center text-sm text-ink/60" data-testid="team-empty">
            No team members yet.
          </div>
        )}
        {!members.isLoading && !members.isError && rows.length > 0 && (
          <table className="w-full text-sm">
            <thead className="bg-bone/60">
              <tr>
                <Th>Name</Th>
                <Th>Role</Th>
                <Th>Position</Th>
                <Th>Status</Th>
                {canManage && <Th>Email</Th>}
                {canViewPay && <Th testId="team-pay-col">Pay</Th>}
                {canManage && <Th> </Th>}
              </tr>
            </thead>
            <tbody>
              {rows.map((m) => (
                <MemberRow
                  key={m.id}
                  member={m}
                  storeId={storeId!}
                  actorRank={caps.rank}
                  canManage={canManage}
                  canViewPay={canViewPay}
                  canManagePay={canManagePay}
                  positions={positionList}
                />
              ))}
            </tbody>
          </table>
        )}
      </div>

      {canManage && storeId && <PendingInvitations storeId={storeId} />}
    </div>
  );
}

function MemberRow({
  member,
  storeId,
  actorRank,
  canManage,
  canViewPay,
  canManagePay,
  positions,
}: {
  member: StoreMember;
  storeId: string;
  actorRank: number;
  canManage: boolean;
  canViewPay: boolean;
  canManagePay: boolean;
  positions: Position[];
}) {
  const terminated = member.status === 'terminated';

  return (
    <tr
      data-testid={`team-row-${member.id}`}
      className={`border-t border-forest/10 ${terminated ? 'text-ink/50' : ''}`}
    >
      <td className="px-4 py-3 font-medium text-ink">{member.name ?? '—'}</td>
      <td className="px-4 py-3">
        <MemberRoleBadge role={member.role} />
      </td>
      <td className="px-4 py-3 text-ink/70">{member.default_position?.name ?? '—'}</td>
      <td className="px-4 py-3">
        <span
          data-testid="member-status"
          className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium ${
            terminated ? 'bg-bone text-ink/60' : 'bg-forest/10 text-forest'
          }`}
        >
          {terminated ? 'Terminated' : 'Active'}
        </span>
      </td>
      {canManage && <td className="px-4 py-3 text-ink/70">{member.email ?? '—'}</td>}
      {canViewPay && (
        <td className="px-4 py-3 text-ink/70">
          <PayRateDialog
            storeId={storeId}
            member={member}
            canManage={canManagePay}
            trigger={
              <button
                type="button"
                data-testid={`team-pay-${member.id}`}
                className="text-forest hover:underline"
              >
                {member.current_pay_rate_cents != null
                  ? `${formatPrice(member.current_pay_rate_cents)}/hr`
                  : 'Set rate'}
              </button>
            }
          />
        </td>
      )}
      {canManage && (
        <td className="px-4 py-3 text-right">
          <EditMemberDialog
            storeId={storeId}
            member={member}
            actorRank={actorRank}
            positions={positions}
            trigger={
              <button
                type="button"
                data-testid={`team-edit-${member.id}`}
                className="text-sm text-forest hover:underline"
              >
                Edit
              </button>
            }
          />
        </td>
      )}
    </tr>
  );
}

function PendingInvitations({ storeId }: { storeId: string }) {
  const invitations = useStoreInvitations(storeId);
  const revoke = useRevokeInvitation();
  const list = invitations.data?.data ?? [];

  if (invitations.isLoading || list.length === 0) return null;

  return (
    <div className="mt-8" data-testid="team-invitations">
      <h2 className="text-lg font-semibold text-ink">Pending invitations</h2>
      <div className="mt-2 overflow-hidden rounded-md border border-forest/20 bg-white">
        <table className="w-full text-sm">
          <thead className="bg-bone/60">
            <tr>
              <Th>Email</Th>
              <Th>Role</Th>
              <Th>Expires</Th>
              <Th> </Th>
            </tr>
          </thead>
          <tbody>
            {list.map((inv) => (
              <tr key={inv.id} className="border-t border-forest/10" data-testid={`invite-row-${inv.id}`}>
                <td className="px-4 py-3 text-ink">{inv.email}</td>
                <td className="px-4 py-3">
                  <MemberRoleBadge role={inv.role} />
                </td>
                <td className="px-4 py-3 text-ink/70">
                  {new Date(inv.expires_at).toLocaleDateString()}
                </td>
                <td className="px-4 py-3 text-right">
                  <button
                    type="button"
                    data-testid={`invite-revoke-${inv.id}`}
                    onClick={() => revoke.mutate({ storeId, invitationId: inv.id })}
                    disabled={revoke.isPending}
                    className="text-sm text-terracotta hover:underline disabled:opacity-50"
                  >
                    Revoke
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function Th({ children, testId }: { children: React.ReactNode; testId?: string }) {
  return (
    <th
      data-testid={testId}
      className="px-4 py-2 text-left text-xs font-medium uppercase tracking-wide text-ink/60"
    >
      {children}
    </th>
  );
}
