import { useState } from 'react';
import { useAuthStore } from '../../auth/auth-store';
import { StatusBadge } from '../../components/admin/StatusBadge';
import { RefreshableCard } from '../../components/admin/RefreshableCard';
import { ConfirmDeleteDialog } from '../../components/admin/ConfirmDeleteDialog';
import {
  useDatabaseStatus,
  useDatabasePool,
  useDatabaseTables,
  useDatabaseQueries,
  useKillQuery,
} from '../../api/queries/admin/database';
import { useThresholds, useSaveThresholds, type ThresholdConfig } from '../../api/queries/admin/thresholds';
import styles from './DatabaseAdminPage.module.css';

export function DatabaseAdminPage() {
  const roles = useAuthStore((s) => s.roles);

  if (!roles.includes('ADMIN')) {
    return (
      <div className={styles.page}>
        <div className={styles.accessDenied}>
          Access Denied — this page requires the ADMIN role.
        </div>
      </div>
    );
  }

  return <DatabaseAdminContent />;
}

function DatabaseAdminContent() {
  const status = useDatabaseStatus();
  const pool = useDatabasePool();
  const tables = useDatabaseTables();
  const queries = useDatabaseQueries();
  const thresholds = useThresholds();

  if (status.isLoading) {
    return (
      <div className={styles.page}>
        <h1 className={styles.pageTitle}>Database Administration</h1>
        <div className={styles.loading}>Loading...</div>
      </div>
    );
  }

  const db = status.data;

  return (
    <div className={styles.page}>
      <div className={styles.header}>
        <div className={styles.headerInfo}>
          <h1 className={styles.pageTitle}>Database Administration</h1>
          <div className={styles.headerMeta}>
            <StatusBadge
              status={db?.connected ? 'healthy' : 'critical'}
              label={db?.connected ? 'Connected' : 'Disconnected'}
            />
            {db?.version && <span className={styles.metaItem}>{db.version}</span>}
            {db?.host && <span className={styles.metaItem}>{db.host}</span>}
            {db?.schema && <span className={styles.metaItem}>Schema: {db.schema}</span>}
          </div>
        </div>
        <button
          type="button"
          className={styles.globalRefresh}
          onClick={() => {
            status.refetch();
            pool.refetch();
            tables.refetch();
            queries.refetch();
          }}
        >
          Refresh All
        </button>
      </div>

      <PoolSection
        pool={pool}
        warningPct={thresholds.data?.database?.connectionPoolWarning}
        criticalPct={thresholds.data?.database?.connectionPoolCritical}
      />
      <TablesSection tables={tables} />
      <QueriesSection
        queries={queries}
        warningSeconds={thresholds.data?.database?.queryDurationWarning}
      />
      <MaintenanceSection />
      <ThresholdsSection thresholds={thresholds.data} />
    </div>
  );
}

function PoolSection({
  pool,
  warningPct,
  criticalPct,
}: {
  pool: ReturnType<typeof useDatabasePool>;
  warningPct?: number;
  criticalPct?: number;
}) {
  const data = pool.data;
  if (!data) return null;

  const usagePct = data.maxPoolSize > 0
    ? Math.round((data.activeConnections / data.maxPoolSize) * 100)
    : 0;
  const barColor =
    criticalPct && usagePct >= criticalPct ? '#ef4444'
    : warningPct && usagePct >= warningPct ? '#eab308'
    : '#22c55e';

  return (
    <RefreshableCard
      title="Connection Pool"
      onRefresh={() => pool.refetch()}
      isRefreshing={pool.isFetching}
      autoRefresh
    >
      <div className={styles.progressContainer}>
        <div className={styles.progressLabel}>
          {data.activeConnections} / {data.maxPoolSize} connections
          <span className={styles.progressPct}>{usagePct}%</span>
        </div>
        <div className={styles.progressBar}>
          <div
            className={styles.progressFill}
            style={{ width: `${usagePct}%`, background: barColor }}
          />
        </div>
      </div>
      <div className={styles.metricsGrid}>
        <div className={styles.metric}>
          <span className={styles.metricValue}>{data.activeConnections}</span>
          <span className={styles.metricLabel}>Active</span>
        </div>
        <div className={styles.metric}>
          <span className={styles.metricValue}>{data.idleConnections}</span>
          <span className={styles.metricLabel}>Idle</span>
        </div>
        <div className={styles.metric}>
          <span className={styles.metricValue}>{data.pendingThreads}</span>
          <span className={styles.metricLabel}>Pending</span>
        </div>
        <div className={styles.metric}>
          <span className={styles.metricValue}>{data.maxWaitMs}ms</span>
          <span className={styles.metricLabel}>Max Wait</span>
        </div>
      </div>
    </RefreshableCard>
  );
}

function TablesSection({ tables }: { tables: ReturnType<typeof useDatabaseTables> }) {
  const data = tables.data;

  return (
    <RefreshableCard
      title="Table Sizes"
      onRefresh={() => tables.refetch()}
      isRefreshing={tables.isFetching}
    >
      {!data ? (
        <div className={styles.loading}>Loading...</div>
      ) : (
        <div className={styles.tableWrapper}>
          <table className={styles.table}>
            <thead>
              <tr>
                <th>Table</th>
                <th>Rows</th>
                <th>Data Size</th>
                <th>Index Size</th>
              </tr>
            </thead>
            <tbody>
              {data.map((t) => (
                <tr key={t.tableName}>
                  <td className={styles.mono}>{t.tableName}</td>
                  <td>{t.rowCount.toLocaleString()}</td>
                  <td>{t.dataSize}</td>
                  <td>{t.indexSize}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </RefreshableCard>
  );
}

function QueriesSection({
  queries,
  warningSeconds,
}: {
  queries: ReturnType<typeof useDatabaseQueries>;
  warningSeconds?: number;
}) {
  const [killTarget, setKillTarget] = useState<number | null>(null);
  const killMutation = useKillQuery();
  const data = queries.data;

  const warningSec = warningSeconds ?? 30;

  return (
    <RefreshableCard
      title="Active Queries"
      onRefresh={() => queries.refetch()}
      isRefreshing={queries.isFetching}
      autoRefresh
    >
      {!data || data.length === 0 ? (
        <div className={styles.emptyState}>No active queries</div>
      ) : (
        <div className={styles.tableWrapper}>
          <table className={styles.table}>
            <thead>
              <tr>
                <th>PID</th>
                <th>Duration</th>
                <th>State</th>
                <th>Query</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {data.map((q) => (
                <tr
                  key={q.pid}
                  className={q.durationSeconds > warningSec ? styles.rowWarning : undefined}
                >
                  <td className={styles.mono}>{q.pid}</td>
                  <td>{formatDuration(q.durationSeconds)}</td>
                  <td>{q.state}</td>
                  <td className={styles.queryCell} title={q.query}>
                    {q.query.length > 100 ? `${q.query.slice(0, 100)}...` : q.query}
                  </td>
                  <td>
                    <button
                      type="button"
                      className={styles.killBtn}
                      onClick={() => setKillTarget(q.pid)}
                    >
                      Kill
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
      <ConfirmDeleteDialog
        isOpen={killTarget !== null}
        onClose={() => setKillTarget(null)}
        onConfirm={() => {
          if (killTarget !== null) {
            killMutation.mutate(killTarget);
            setKillTarget(null);
          }
        }}
        resourceName={String(killTarget ?? '')}
        resourceType="query (PID)"
      />
    </RefreshableCard>
  );
}

function MaintenanceSection() {
  return (
    <RefreshableCard title="Maintenance">
      <div className={styles.maintenanceGrid}>
        <button type="button" className={styles.maintenanceBtn} disabled title="Coming soon">
          VACUUM ANALYZE
        </button>
        <button type="button" className={styles.maintenanceBtn} disabled title="Coming soon">
          REINDEX
        </button>
        <button type="button" className={styles.maintenanceBtn} disabled title="Coming soon">
          Refresh Aggregates
        </button>
      </div>
    </RefreshableCard>
  );
}

function ThresholdsSection({ thresholds }: { thresholds?: ThresholdConfig }) {
  const [form, setForm] = useState<ThresholdConfig | null>(null);
  const saveMutation = useSaveThresholds();
  const [status, setStatus] = useState<{ type: 'success' | 'error'; msg: string } | null>(null);

  const current = form ?? thresholds;
  if (!current) return null;

  function updateDb(key: keyof ThresholdConfig['database'], value: number) {
    setForm((prev) => {
      const base = prev ?? thresholds!;
      return { ...base, database: { ...base.database, [key]: value } };
    });
  }

  async function handleSave() {
    if (!form && !thresholds) return;
    const data = form ?? thresholds!;
    try {
      await saveMutation.mutateAsync(data);
      setStatus({ type: 'success', msg: 'Thresholds saved.' });
      setTimeout(() => setStatus(null), 3000);
    } catch {
      setStatus({ type: 'error', msg: 'Failed to save thresholds.' });
    }
  }

  return (
    <RefreshableCard title="Thresholds" collapsible defaultCollapsed>
      <div className={styles.thresholdGrid}>
        <div className={styles.thresholdField}>
          <label className={styles.thresholdLabel}>Pool Warning %</label>
          <input
            type="number"
            className={styles.thresholdInput}
            value={current.database.connectionPoolWarning}
            onChange={(e) => updateDb('connectionPoolWarning', Number(e.target.value))}
          />
        </div>
        <div className={styles.thresholdField}>
          <label className={styles.thresholdLabel}>Pool Critical %</label>
          <input
            type="number"
            className={styles.thresholdInput}
            value={current.database.connectionPoolCritical}
            onChange={(e) => updateDb('connectionPoolCritical', Number(e.target.value))}
          />
        </div>
        <div className={styles.thresholdField}>
          <label className={styles.thresholdLabel}>Query Warning (s)</label>
          <input
            type="number"
            className={styles.thresholdInput}
            value={current.database.queryDurationWarning}
            onChange={(e) => updateDb('queryDurationWarning', Number(e.target.value))}
          />
        </div>
        <div className={styles.thresholdField}>
          <label className={styles.thresholdLabel}>Query Critical (s)</label>
          <input
            type="number"
            className={styles.thresholdInput}
            value={current.database.queryDurationCritical}
            onChange={(e) => updateDb('queryDurationCritical', Number(e.target.value))}
          />
        </div>
      </div>
      <div className={styles.thresholdActions}>
        <button
          type="button"
          className={styles.btnPrimary}
          onClick={handleSave}
          disabled={saveMutation.isPending}
        >
          {saveMutation.isPending ? 'Saving...' : 'Save Thresholds'}
        </button>
        {status && (
          <span className={status.type === 'success' ? styles.successMsg : styles.errorMsg}>
            {status.msg}
          </span>
        )}
      </div>
    </RefreshableCard>
  );
}

function formatDuration(seconds: number): string {
  if (seconds < 1) return `${Math.round(seconds * 1000)}ms`;
  const s = Math.floor(seconds);
  if (s < 60) return `${s}s`;
  const m = Math.floor(s / 60);
  return `${m}m ${s % 60}s`;
}
