import {RefreshCw} from 'lucide-react';
import {useCallback, useEffect, useState} from 'react';

import {getAdminOverview} from '../api/adminApiClient';
import type {
  AdminDatabaseTableStatPayload,
  AdminOverviewResponse,
} from '../api/adminApiTypes';
import {handlePageError} from './pageUtils';

interface AdminOverviewPageProps {
  token: string;
  onUnauthorized: (message?: string) => void;
}

export function AdminOverviewPage({
  token,
  onUnauthorized,
}: AdminOverviewPageProps) {
  const [overview, setOverview] = useState<AdminOverviewResponse | null>(null);
  const [errorMessage, setErrorMessage] = useState('');
  const [isLoading, setIsLoading] = useState(false);

  const loadOverview = useCallback(async () => {
    setIsLoading(true);
    setErrorMessage('');
    try {
      const response = await getAdminOverview(token);
      setOverview(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsLoading(false);
    }
  }, [onUnauthorized, token]);

  useEffect(() => {
    void loadOverview();
  }, [loadOverview]);

  return (
    <section className="admin-page">
      <div className="admin-page-heading">
        <div>
          <h2>总览</h2>
          <p>服务与数据库状态</p>
        </div>
        <button
          className="admin-secondary-button"
          disabled={isLoading}
          type="button"
          onClick={() => void loadOverview()}
        >
          <RefreshCw size={17} aria-hidden="true" />
          <span>{isLoading ? '刷新中' : '刷新'}</span>
        </button>
      </div>

      {errorMessage ? (
        <div className="admin-alert" role="status">
          {errorMessage}
        </div>
      ) : null}

      <div className="admin-overview-grid">
        <InfoPanel
          title="服务"
          rows={[
            ['监听', overview ? `${overview.service.bindHost}:${overview.service.bindPort}` : '-'],
            ['JWT issuer', overview?.service.jwtIssuer ?? '-'],
            ['后台', overview?.service.adminEnabled ? '已启用' : '未启用'],
          ]}
        />
        <InfoPanel
          title="SpacetimeDB"
          rows={[
            ['Server', overview?.service.spacetimeServerUrl ?? '-'],
            ['Database', overview?.service.spacetimeDatabase ?? '-'],
            ['Identity', overview?.database.databaseIdentity ?? '-'],
            ['Owner', overview?.database.ownerIdentity ?? '-'],
            ['Host', overview?.database.hostType ?? '-'],
          ]}
        />
      </div>

      <section className="admin-panel">
        <div className="admin-panel-heading">
          <h3>表统计</h3>
          <span>{overview?.database.schemaTableNames.length ?? 0} tables</span>
        </div>
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>表</th>
                <th>行数</th>
                <th>状态</th>
              </tr>
            </thead>
            <tbody>
              {(overview?.database.tableStats ?? []).map((stat) => (
                <TableStatRow key={stat.tableName} stat={stat} />
              ))}
              {overview && overview.database.tableStats.length === 0 ? (
                <tr>
                  <td colSpan={3}>暂无统计</td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </section>

      {overview?.database.fetchErrors.length ? (
        <section className="admin-panel admin-panel-warning">
          <div className="admin-panel-heading">
            <h3>读取异常</h3>
            <span>{overview.database.fetchErrors.length}</span>
          </div>
          <ul className="admin-error-list">
            {overview.database.fetchErrors.map((message) => (
              <li key={message}>{message}</li>
            ))}
          </ul>
        </section>
      ) : null}
    </section>
  );
}

function InfoPanel({
  title,
  rows,
}: {
  title: string;
  rows: Array<[string, string]>;
}) {
  return (
    <section className="admin-panel">
      <div className="admin-panel-heading">
        <h3>{title}</h3>
      </div>
      <dl className="admin-info-list">
        {rows.map(([label, value]) => (
          <div key={label}>
            <dt>{label}</dt>
            <dd>{value}</dd>
          </div>
        ))}
      </dl>
    </section>
  );
}

function TableStatRow({stat}: {stat: AdminDatabaseTableStatPayload}) {
  return (
    <tr>
      <td>
        <button
          className="admin-text-button"
          type="button"
          onClick={() => {
            window.location.hash = `#tables?table=${encodeURIComponent(stat.tableName)}`;
          }}
        >
          {stat.tableName}
        </button>
      </td>
      <td>{typeof stat.rowCount === 'number' ? stat.rowCount : '-'}</td>
      <td>
        {stat.errorMessage ? (
          <span className="admin-status admin-status-error">
            {stat.errorMessage}
          </span>
        ) : (
          <span className="admin-status admin-status-ok">OK</span>
        )}
      </td>
    </tr>
  );
}
