'use client';

/**
 * At-Risk Dealers Panel
 *
 * Compliance surface for the admin dashboard. Fetches /api/admin/at-risk and
 * shows dealers who appear set up but are missing a ZO number and/or subdomain
 * — the two issues that silently block commissions / reachability.
 *
 * Each row's "Inspect" button hands the dealer's email back to the page via
 * onInspect, so the existing dealer search + detail modal handle the triage
 * (this panel intentionally does not duplicate that machinery).
 */

import React, { useEffect, useState } from 'react';
import styles from './AtRiskPanel.module.css';

type IssueCode = 'missing_zo' | 'missing_subdomain';

interface AtRiskDealer {
  id: string;
  businessName: string | null;
  contactName: string | null;
  subdomain: string | null;
  dealerNumber: string | null;
  status: string;
  createdAt: string;
  email: string;
  name: string | null;
  issues: IssueCode[];
}

interface AtRiskResponse {
  success: boolean;
  counts: { missingZo: number; missingSubdomain: number; total: number };
  dealers: AtRiskDealer[];
}

interface AtRiskPanelProps {
  /** Called with the dealer's email so the page can drive the existing dealer search. */
  onInspect: (searchValue: string) => void;
  /** Called with the dealer's id to open the detail modal directly (panel stays open). */
  onViewDetails: (dealerId: string) => void;
}

const ISSUE_LABELS: Record<IssueCode, string> = {
  missing_zo: 'ZO',
  missing_subdomain: 'Subdomain',
};

function daysSince(iso: string): number {
  const ms = Date.now() - new Date(iso).getTime();
  return Math.max(0, Math.floor(ms / 86_400_000));
}

const PAGE_SIZE = 100;

export function AtRiskPanel({ onInspect, onViewDetails }: AtRiskPanelProps) {
  const [data, setData] = useState<AtRiskResponse | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(0);
  const [activeFilter, setActiveFilter] = useState<IssueCode | null>(null);

  useEffect(() => {
    let cancelled = false;

    async function load() {
      try {
        setIsLoading(true);
        setError(null);
        const params = new URLSearchParams({
          limit: String(PAGE_SIZE),
          offset: String(page * PAGE_SIZE),
        });
        const res = await fetch(`/api/admin/at-risk?${params}`);
        const body = (await res.json()) as AtRiskResponse & { error?: string };
        if (!res.ok || !body.success) {
          throw new Error(body?.error || 'Failed to build at-risk report');
        }
        if (!cancelled) {
          setData(body);
        }
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : 'Failed to build at-risk report');
        }
      } finally {
        if (!cancelled) {
          setIsLoading(false);
        }
      }
    }

    load();
    return () => {
      cancelled = true;
    };
  }, [page]);

  return (
    <section className={styles.panel}>
      <h2 className={styles.title}>At-Risk Dealers</h2>

      {isLoading && (
        <div className={styles.loading} data-testid="at-risk-loading">
          <div className={styles.skeletonChip} />
          <div className={styles.skeletonChip} />
        </div>
      )}

      {!isLoading && error && (
        <div className={styles.error} role="alert">
          <p>{error}</p>
        </div>
      )}

      {!isLoading && !error && data && data.counts.total === 0 && (
        <p className={styles.empty}>
          All dealers have a ZO number and subdomain. Nothing needs attention.
        </p>
      )}

      {!isLoading && !error && data && data.counts.total > 0 && (
        <>
          <div className={styles.chipRow}>
            <button
              type="button"
              className={`${styles.countChip} ${styles.zo}${activeFilter === 'missing_zo' ? ` ${styles['countChip--active']}` : ''}`}
              onClick={() => setActiveFilter((f) => (f === 'missing_zo' ? null : 'missing_zo'))}
              aria-pressed={activeFilter === 'missing_zo'}
              aria-label={`Filter by missing ZO (${data.counts.missingZo} dealers)`}
            >
              <span className={styles.countValue} data-testid="count-missing-zo">
                {data.counts.missingZo}
              </span>
              <span className={styles.countLabel}>Missing ZO</span>
            </button>
            <button
              type="button"
              className={`${styles.countChip} ${styles.subdomain}${activeFilter === 'missing_subdomain' ? ` ${styles['countChip--active']}` : ''}`}
              onClick={() =>
                setActiveFilter((f) => (f === 'missing_subdomain' ? null : 'missing_subdomain'))
              }
              aria-pressed={activeFilter === 'missing_subdomain'}
              aria-label={`Filter by missing subdomain (${data.counts.missingSubdomain} dealers)`}
            >
              <span className={styles.countValue} data-testid="count-missing-subdomain">
                {data.counts.missingSubdomain}
              </span>
              <span className={styles.countLabel}>Missing Subdomain</span>
            </button>
            {activeFilter !== null && (
              <button
                type="button"
                className={styles.filterClear}
                onClick={() => setActiveFilter(null)}
                aria-label="Clear filter, show all dealers"
              >
                Show all
              </button>
            )}
          </div>

          <div className={styles.tableWrap}>
            <table className={styles.table}>
              <thead>
                <tr>
                  <th>Dealer</th>
                  <th>Email</th>
                  <th>Issues</th>
                  <th>Age</th>
                  <th aria-label="Actions" />
                </tr>
              </thead>
              <tbody>
                {(activeFilter
                  ? data.dealers.filter((d) => d.issues.includes(activeFilter))
                  : data.dealers
                ).map((dealer) => (
                  <tr key={dealer.id}>
                    <td>{dealer.businessName || dealer.contactName || dealer.name || '—'}</td>
                    <td className={styles.email}>{dealer.email}</td>
                    <td className={styles.issueCell}>
                      {dealer.issues.map((issue) => (
                        <span
                          key={issue}
                          className={`${styles.issueChip} ${
                            issue === 'missing_zo' ? styles.zo : styles.subdomain
                          }`}
                        >
                          {ISSUE_LABELS[issue]}
                        </span>
                      ))}
                    </td>
                    <td className={styles.age}>{daysSince(dealer.createdAt)}d</td>
                    <td>
                      <div className={styles.actions}>
                        <button
                          type="button"
                          className={styles.inspectButton}
                          onClick={() => onViewDetails(dealer.id)}
                        >
                          View details
                        </button>
                        <button
                          type="button"
                          className={styles.secondaryButton}
                          onClick={() => onInspect(dealer.email)}
                        >
                          Show in table
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {data.counts.total > PAGE_SIZE && (
              <div className={styles.pagination}>
                <span>
                  Showing {data.dealers.length ? page * PAGE_SIZE + 1 : 0}–
                  {page * PAGE_SIZE + data.dealers.length} of {data.counts.total}
                </span>
                <span>
                  <button
                    type="button"
                    className={styles.pageBtn}
                    disabled={page === 0}
                    onClick={() => setPage((p) => Math.max(0, p - 1))}
                  >
                    &larr;
                  </button>{' '}
                  Page {page + 1} of {Math.max(1, Math.ceil(data.counts.total / PAGE_SIZE))}{' '}
                  <button
                    type="button"
                    className={styles.pageBtn}
                    disabled={(page + 1) * PAGE_SIZE >= data.counts.total}
                    onClick={() => setPage((p) => p + 1)}
                  >
                    &rarr;
                  </button>
                </span>
              </div>
            )}
          </div>
        </>
      )}
    </section>
  );
}
