import { motion } from 'framer-motion';
import { useNavigate } from 'react-router-dom';
import styles from './OracleResultCard.module.css';

type OracleRow = Record<string, unknown>;

interface OracleResult {
  title?: string;
  summary?: string;
  columns?: string[];
  rows?: OracleRow[];
  rowCount?: number;
  componentType?: 'bar' | 'list' | 'metric' | 'table' | string;
  warnings?: string[];
  sourceTables?: string[];
}

interface OracleResultCardProps {
  result: OracleResult;
  query: string;
}

function displayValue(value: unknown): string {
  if (value == null || value === '') return '-';
  if (typeof value === 'number') {
    return Number.isInteger(value) ? value.toLocaleString('en-IN') : value.toLocaleString('en-IN', { maximumFractionDigits: 2 });
  }
  if (typeof value === 'boolean') return value ? 'Yes' : 'No';
  if (value instanceof Date) return value.toLocaleString();
  if (typeof value === 'object') return JSON.stringify(value);
  return String(value);
}

function inferLabel(row: OracleRow): string {
  const preferred = ['name', 'full_name', 'client_name', 'project_name', 'title', 'label'];
  const key = preferred.find((candidate) => row[candidate] != null);
  if (key) return displayValue(row[key]);
  const first = Object.values(row).find((value) => value != null);
  return displayValue(first);
}

function inferValue(row: OracleRow): string {
  const preferred = ['value', 'score', 'qd_score', 'count', 'total', 'amount', 'interest_count'];
  const key = preferred.find((candidate) => row[candidate] != null);
  if (key) return displayValue(row[key]);
  const values = Object.values(row).filter((value) => value != null);
  return displayValue(values[1] ?? values[0]);
}

function personIdFromRow(row: OracleRow): string | undefined {
  const raw = row.person_id ?? row.client_id ?? row.lead_id ?? row.id;
  return typeof raw === 'string' && raw.length > 0 ? raw : undefined;
}

export function OracleResultCard({ result, query }: OracleResultCardProps) {
  const navigate = useNavigate();
  const rows = Array.isArray(result.rows) ? result.rows : [];
  const columns = Array.isArray(result.columns) && result.columns.length > 0
    ? result.columns
    : rows[0]
      ? Object.keys(rows[0])
      : [];
  const type = result.componentType ?? (columns.length > 4 ? 'table' : 'list');
  const firstPersonId = rows.map(personIdFromRow).find(Boolean);

  return (
    <motion.div
      className={`${styles.card} glass-card`}
      initial={{ opacity: 0, y: 12 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}
    >
      <div className={styles.header}>
        <p className={styles.summary}>
          <span className={styles.aiStar}>✦</span>
          {result.summary || result.title || `Oracle result for "${query}"`}
        </p>
        {typeof result.rowCount === 'number' && (
          <span className={styles.rowCount}>{result.rowCount.toLocaleString('en-IN')} rows</span>
        )}
      </div>

      {rows.length === 0 && (
        <div className={styles.empty}>
          {result.title || 'No rows returned'}
          {result.warnings?.length ? <small>{result.warnings[0]}</small> : null}
        </div>
      )}

      {rows.length > 0 && type === 'metric' && (
        <motion.div
          className={styles.metric}
          initial={{ opacity: 0, scale: 0.95 }}
          animate={{ opacity: 1, scale: 1 }}
          transition={{ delay: 0.2 }}
        >
          <span className={styles.metricValue}>{inferValue(rows[0])}</span>
          <span className={styles.metricLabel}>{inferLabel(rows[0])}</span>
        </motion.div>
      )}

      {rows.length > 0 && type !== 'metric' && columns.length <= 4 && (
        <div className={styles.list}>
          {rows.slice(0, 8).map((row, i) => (
            <motion.div
              key={i}
              className={styles.listRow}
              initial={{ opacity: 0, x: -8 }}
              animate={{ opacity: 1, x: 0 }}
              transition={{ delay: 0.15 + i * 0.08, duration: 0.25 }}
            >
              <span className={styles.rowLabel}>{inferLabel(row)}</span>
              <span className={styles.rowValue}>{inferValue(row)}</span>
            </motion.div>
          ))}
        </div>
      )}

      {rows.length > 0 && type !== 'metric' && columns.length > 4 && (
        <div className={styles.tableWrap}>
          <table className={styles.table}>
            <thead>
              <tr>{columns.slice(0, 6).map((column) => <th key={column}>{column.replace(/_/g, ' ')}</th>)}</tr>
            </thead>
            <tbody>
              {rows.slice(0, 8).map((row, rowIndex) => (
                <motion.tr
                  key={rowIndex}
                  initial={{ opacity: 0, y: 6 }}
                  animate={{ opacity: 1, y: 0 }}
                  transition={{ delay: 0.12 + rowIndex * 0.05, duration: 0.2 }}
                >
                  {columns.slice(0, 6).map((column) => <td key={column}>{displayValue(row[column])}</td>)}
                </motion.tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {(firstPersonId || result.sourceTables?.length) && (
        <div className={styles.actionRow}>
          {firstPersonId && (
            <button className="btn-ghost" onClick={() => navigate(`/pipeline/${firstPersonId}`)}>
              Open top client
            </button>
          )}
          {result.sourceTables?.length ? (
            <span className={styles.provenance}>{result.sourceTables.slice(0, 4).join(', ')}</span>
          ) : null}
        </div>
      )}
    </motion.div>
  );
}
