'use client';

/**
 * AdminSupportInbox — paginated inbox of support tickets + cases.
 * Polls every 15s. Claim button for unassigned items.
 */

import { useState } from 'react';
import { useT, useLocale } from '@/lib/i18n/react';
import type { AdminInboxQuery } from '@/server/schemas/support/admin';
import { HydratedIsland } from '@/components/HydratedIsland';
import { AdminTable } from '@/components/ui/domain/admin/AdminTable';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { Button } from '@/components/ui/primitives/Button';
import { Skeleton, TableSkeleton } from '@/components/ui/feedback/Skeleton';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { SLABadge } from '@/components/ui/domain/support/SLABadge';
import { ConfidenceBar } from '@/components/ui/primitives/ConfidenceBar';
import { Pill } from '@/components/ui/primitives/Pill';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
} from '@/components/ui/primitives/Select';
import { Row } from '@/components/ui/layout/Row';
import { Stack } from '@/components/ui/layout/Stack';
import { QueryBoundary } from '@platform-modules/ui-primitives';
import { useInbox, useInboxIsFetching, useClaim } from './internals/useAdminSupport';
import type { InboxRow } from '@/pages/api/admin/support/inbox';
import { formatDate } from '@/lib/format';

function readInboxQueryFromUrl(): Partial<AdminInboxQuery> {
  if (typeof window === 'undefined') return {};
  const params = new URLSearchParams(window.location.search);
  const next: Partial<AdminInboxQuery> = {};
  const type = params.get('type');
  if (type === 'ticket' || type === 'case' || type === 'all') next.type = type;
  const assigned = params.get('assigned');
  if (assigned === 'me' || assigned === 'unassigned' || assigned === 'any') {
    next.assigned = assigned;
  }
  const status = params.get('status');
  if (status) next.status = status;
  const slaBreach = params.get('slaBreach');
  if (slaBreach === 'breached' || slaBreach === 'warning' || slaBreach === 'healthy') {
    next.slaBreach = slaBreach;
  }
  return next;
}

function filterTriggerLabel(prefix: string, valueLabel: string) {
  return `${prefix}: ${valueLabel}`;
}

function InboxSkeleton() {
  return (
    <Stack gap="4">
      <TableSkeleton rows={6} cols={8} />
      <Skeleton className="h-9 w-40 self-end" />
    </Stack>
  );
}

function InboxInner() {
  const t = useT('admin');
  const tCommon = useT('common');
  const { locale } = useLocale();
  const ts = t('support') as unknown as Record<string, string>;

  const [query, setQuery] = useState<AdminInboxQuery>(() => ({
    type: 'all',
    slaBreach: 'any',
    assigned: 'any',
    page: 1,
    pageSize: 25,
    sort: 'sla_soonest',
    ...readInboxQueryFromUrl(),
  }));

  const inboxQuery = useInbox(query);
  const isFetching = useInboxIsFetching();

  function setFilter(key: keyof AdminInboxQuery, value: string) {
    setQuery((q) => ({ ...q, [key]: value, page: 1 }));
  }

  return (
    <div>
      <Row gap="3" align="center" className="mb-2 flex-wrap">
        <PageHeader title={ts.inbox_title ?? ''} />
        {isFetching > 0 && <span className="text-text-muted text-xs">{ts.inbox_polling}</span>}
      </Row>

      {/* Filters */}
      <div
        role="toolbar"
        aria-label={ts.filter_type ?? 'Filters'}
        className="mb-4 flex flex-wrap gap-2"
      >
        <Select value={query.type} onValueChange={(v) => setFilter('type', v)}>
          <SelectTrigger className="w-40" aria-label={ts.filter_type}>
            <span className="truncate">
              {filterTriggerLabel(
                ts.filter_type ?? '',
                ts[`type_${query.type}`] ?? ts.type_all ?? '',
              )}
            </span>
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">{ts.type_all}</SelectItem>
            <SelectItem value="ticket">{ts.type_ticket}</SelectItem>
            <SelectItem value="case">{ts.type_case}</SelectItem>
          </SelectContent>
        </Select>

        <Select value={query.slaBreach} onValueChange={(v) => setFilter('slaBreach', v)}>
          <SelectTrigger className="w-44" aria-label={ts.filter_sla}>
            <span className="truncate">
              {filterTriggerLabel(
                ts.filter_sla ?? '',
                query.slaBreach === 'any'
                  ? (ts.sla_any ?? '')
                  : (ts[`sla_${query.slaBreach}`] ?? ''),
              )}
            </span>
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="any">{ts.sla_any}</SelectItem>
            <SelectItem value="breached">{ts.sla_breached}</SelectItem>
            <SelectItem value="warning">{ts.sla_warning}</SelectItem>
            <SelectItem value="healthy">{ts.sla_healthy}</SelectItem>
          </SelectContent>
        </Select>

        <Select value={query.assigned} onValueChange={(v) => setFilter('assigned', v)}>
          <SelectTrigger className="w-40" aria-label={ts.filter_assigned}>
            <span className="truncate">
              {filterTriggerLabel(
                ts.filter_assigned ?? '',
                ts[`assigned_${query.assigned}`] ?? ts.assigned_any ?? '',
              )}
            </span>
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="any">{ts.assigned_any}</SelectItem>
            <SelectItem value="unassigned">{ts.assigned_unassigned}</SelectItem>
            <SelectItem value="me">{ts.assigned_me}</SelectItem>
          </SelectContent>
        </Select>

        <Select value={query.sort} onValueChange={(v) => setFilter('sort', v)}>
          <SelectTrigger className="w-48" aria-label={ts.filter_sort}>
            <span className="truncate">
              {filterTriggerLabel(ts.filter_sort ?? '', ts[`sort_${query.sort}`] ?? '')}
            </span>
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="sla_soonest">{ts.sort_sla_soonest}</SelectItem>
            <SelectItem value="updated_desc">{ts.sort_updated_desc}</SelectItem>
            <SelectItem value="created_desc">{ts.sort_created_desc}</SelectItem>
          </SelectContent>
        </Select>
      </div>

      <QueryBoundary
        query={inboxQuery}
        skeleton={<InboxSkeleton />}
        errorFallback={() => (
          <ErrorState
            title={ts.inbox_load_error ?? ''}
            action={
              <Button variant="secondary" size="sm" onClick={() => window.location.reload()}>
                {tCommon('retry')}
              </Button>
            }
            className="mb-4 py-6"
          />
        )}
      >
        {(resolved) => {
          const rows: InboxRow[] = (resolved.rows as InboxRow[]) ?? [];
          const total = (resolved.total as number) ?? 0;
          const totalPages = Math.ceil(total / query.pageSize);

          if (rows.length === 0) {
            return <EmptyState title={ts.inbox_empty ?? ''} />;
          }

          return (
            <>
              <AdminTable<InboxRow>
                columns={[
                  {
                    key: 'type',
                    label: ts.col_type ?? '',
                    render: (r) => (
                      <span className="text-xs" data-type={r.type}>
                        {ts[`type_${r.type}`] ?? ''}
                      </span>
                    ),
                  },
                  {
                    key: 'subject',
                    label: ts.col_subject ?? '',
                    render: (r) => <span data-display-name>{r.subject}</span>,
                  },
                  {
                    key: 'status',
                    label: ts.col_status ?? '',
                    render: (r) => (
                      <span data-status={r.status}>{ts[`${r.type}_status_${r.status}`] ?? ''}</span>
                    ),
                  },
                  {
                    key: 'sla',
                    label: ts.col_sla ?? '',
                    render: (r) => <SLABadge tone={r.slaState} />,
                  },
                  {
                    key: 'confidence',
                    label: ts.col_confidence ?? '',
                    render: (r) =>
                      r.aiConfidence != null ? (
                        <ConfidenceBar value={r.aiConfidence} />
                      ) : (
                        <span className="text-text-muted text-sm">
                          {ts.confidence_empty ?? '—'}
                        </span>
                      ),
                  },
                  {
                    key: 'priority',
                    label: ts.col_priority ?? '',
                    render: (r) => (
                      <Pill
                        tone={
                          r.priority === 'urgent'
                            ? 'danger'
                            : r.priority === 'high'
                              ? 'warning'
                              : r.priority === 'low'
                                ? 'info'
                                : 'neutral'
                        }
                        size="sm"
                      >
                        {ts[`priority_${r.priority}`] ?? r.priority}
                      </Pill>
                    ),
                  },
                  {
                    key: 'updatedAt',
                    label: ts.col_updated ?? '',
                    render: (r) => formatDate(r.updatedAt, locale),
                  },
                  {
                    key: 'claim',
                    label: '',
                    interactive: true,
                    render: (r) => (
                      <ClaimButton
                        type={r.type}
                        id={r.id}
                        assignedAgentId={r.assignedAgentId}
                        label={ts.action_claim ?? ''}
                      />
                    ),
                  },
                ]}
                rows={rows}
                rowHref={(row) => `/admin/support/${row.type}/${row.id}`}
                loading={false}
              />
              {totalPages > 1 && (
                <div className="mt-4">
                  <Pagination
                    page={query.page}
                    totalPages={totalPages}
                    onPageChange={(p) => setQuery((q) => ({ ...q, page: p }))}
                  />
                </div>
              )}
            </>
          );
        }}
      </QueryBoundary>
    </div>
  );
}

function ClaimButton({
  type,
  id,
  assignedAgentId,
  label,
}: {
  type: 'ticket' | 'case';
  id: string;
  assignedAgentId: string | null;
  label: string;
}) {
  const claim = useClaim(type, id, {
    onSuccess: () => {
      window.location.href = `/admin/support/${type}/${id}`;
    },
  });
  if (assignedAgentId) return null;
  return (
    <Button
      variant="primary"
      size="sm"
      aria-label={label}
      disabled={claim.isPending}
      onClick={(e) => {
        e.preventDefault();
        e.stopPropagation();
        claim.mutate();
      }}
    >
      {claim.isPending ? `${label}…` : label}
    </Button>
  );
}

export function AdminSupportInbox() {
  return (
    <HydratedIsland>
      <InboxInner />
    </HydratedIsland>
  );
}
