import { useState, useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import Editor from '@monaco-editor/react';
import { apiGet, apiPost, apiDelete } from '../api/client';
import { LoadingSpinner, Card } from '../components/ui';
import {
  BarChart, Bar, LineChart, Line, ScatterChart, Scatter,
  XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid,
} from 'recharts';

interface QueryResult {
  columns: Array<{ name: string; type: string }>;
  rows: unknown[][];
  row_count: number;
  elapsed_ms: number;
}

interface SavedQuery {
  id: string;
  name: string;
  description: string;
  sql_text: string;
  created_at: string;
}

interface SchemaInfo {
  catalog: string;
  schema: string;
  tables: Array<{ name: string; columns: Array<{ name: string; type: string; nullable?: boolean }> }>;
}

type ChartType = 'none' | 'bar' | 'line' | 'scatter';

export function SqlExplorerPage() {
  const qc = useQueryClient();
  const [sql, setSql] = useState('SELECT 1 AS test');
  const [result, setResult] = useState<QueryResult | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [chartType, setChartType] = useState<ChartType>('none');
  const [xCol, setXCol] = useState(0);
  const [yCol, setYCol] = useState(1);

  const { data: schema } = useQuery<SchemaInfo>({
    queryKey: ['pg-schema'],
    queryFn: () => apiGet<SchemaInfo>('query', '/api/analytics/pg-schema'),
  });

  const { data: savedQueries } = useQuery<SavedQuery[]>({
    queryKey: ['saved-queries'],
    queryFn: () => apiGet<SavedQuery[]>('query', '/api/analytics/saved-queries'),
  });

  const executeMutation = useMutation({
    mutationFn: (sqlText: string) => apiPost<QueryResult>('query', '/api/analytics/pg-query', { sql: sqlText, limit: 1000 }),
    onSuccess: (data) => { setResult(data); setError(null); },
    onError: (err: Error) => {
      const detail = (err as { body?: { detail?: string } }).body?.detail;
      setError(detail || err.message);
      setResult(null);
    },
  });

  const saveMutation = useMutation({
    mutationFn: (body: { name: string; sql_text: string }) => apiPost<SavedQuery>('query', '/api/analytics/saved-queries', body),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['saved-queries'] }),
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => apiDelete<unknown>('query', `/api/analytics/saved-queries/${id}`),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['saved-queries'] }),
  });

  const handleExecute = useCallback(() => {
    if (sql.trim()) executeMutation.mutate(sql);
  }, [sql, executeMutation]);

  const handleSave = useCallback(() => {
    const name = prompt('Query name:');
    if (name) saveMutation.mutate({ name, sql_text: sql });
  }, [sql, saveMutation]);

  const handleQuickInsert = useCallback((tableName: string) => {
    const query = `SELECT * FROM ${tableName} LIMIT 100`;
    setSql(query);
  }, []);

  // Build chart data from result
  const chartData = result && result.columns.length >= 2
    ? result.rows.map((row) => ({
        x: row[xCol],
        y: Number(row[yCol]) || 0,
        label: String(row[xCol]),
      }))
    : [];

  // Split saved queries into pre-built (no id-based delete) and user-saved
  const preBuiltNames = new Set([
    'Company Overview', 'Recent Recommendations', 'High Confidence Buys',
    'Trend Windows Summary', 'Market Prices', 'Document Counts by Type',
    'Global Events', 'Trading Decisions', 'Ingestion Health',
    'Reserve Pool Ledger', 'Sector Exposure', 'Source Coverage Matrix',
  ]);
  const preBuiltQueries = (savedQueries ?? []).filter((sq) => preBuiltNames.has(sq.name));
  const userQueries = (savedQueries ?? []).filter((sq) => !preBuiltNames.has(sq.name));

  return (
    <div className="flex h-[calc(100vh-3rem)] gap-4">
      {/* Schema browser sidebar */}
      <div className="w-64 shrink-0 overflow-y-auto rounded-lg border border-surface-700 bg-surface-900 p-3">
        <h2 className="mb-2 text-xs font-semibold uppercase tracking-wider text-gray-500">Schema</h2>
        {schema?.tables.map((t) => (
          <div key={t.name} className="mb-2">
            <button
              className="text-xs font-medium text-brand-300 hover:underline"
              onClick={() => handleQuickInsert(t.name)}
              title={`SELECT * FROM ${t.name} LIMIT 100`}
            >
              {t.name}
            </button>
            <div className="ml-2 space-y-0.5">
              {t.columns.map((c) => (
                <div key={c.name} className="flex justify-between text-[10px]">
                  <span className="text-gray-400">{c.name}</span>
                  <span className="text-gray-600">{c.type}</span>
                </div>
              ))}
            </div>
          </div>
        ))}

        {/* Pre-built queries */}
        {preBuiltQueries.length > 0 && (
          <>
            <h2 className="mb-2 mt-4 text-xs font-semibold uppercase tracking-wider text-gray-500">Pre-built Queries</h2>
            {preBuiltQueries.map((sq) => (
              <div key={sq.id} className="mb-1.5">
                <button
                  className="block w-full truncate text-left text-xs text-brand-300 hover:text-brand-200"
                  onClick={() => setSql(sq.sql_text)}
                  title={sq.sql_text}
                >
                  {sq.name}
                </button>
                {sq.description && (
                  <p className="ml-0 truncate text-[10px] text-gray-600" title={sq.description}>
                    {sq.description}
                  </p>
                )}
              </div>
            ))}
          </>
        )}

        {/* User saved queries */}
        <h2 className="mb-2 mt-4 text-xs font-semibold uppercase tracking-wider text-gray-500">Saved Queries</h2>
        {userQueries.length === 0 && (
          <p className="text-[10px] text-gray-600">No saved queries yet</p>
        )}
        {userQueries.map((sq) => (
          <div key={sq.id} className="mb-1 flex items-center justify-between">
            <button
              className="truncate text-xs text-gray-300 hover:text-brand-300"
              onClick={() => setSql(sq.sql_text)}
              title={sq.description || sq.name}
            >
              {sq.name}
            </button>
            <button
              className="text-[10px] text-gray-600 hover:text-red-400"
              onClick={() => deleteMutation.mutate(sq.id)}
              aria-label={`Delete ${sq.name}`}
            >
              ×
            </button>
          </div>
        ))}
      </div>

      {/* Main area */}
      <div className="flex flex-1 flex-col gap-3 overflow-hidden">
        {/* Editor */}
        <div className="h-48 shrink-0 overflow-hidden rounded-lg border border-surface-700">
          <Editor
            height="100%"
            defaultLanguage="sql"
            value={sql}
            onChange={(v) => setSql(v ?? '')}
            theme="vs-dark"
            options={{ minimap: { enabled: false }, fontSize: 13, lineNumbers: 'on', scrollBeyondLastLine: false }}
          />
        </div>

        {/* Controls */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleExecute}
            disabled={executeMutation.isPending}
            className="rounded-md bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50"
          >
            {executeMutation.isPending ? 'Running…' : 'Execute'}
          </button>
          <button onClick={handleSave} className="rounded-md border border-surface-700 px-3 py-1.5 text-sm text-gray-400 hover:bg-surface-800">
            Save
          </button>
          {result && (
            <span className="text-xs text-gray-500">
              {result.row_count} rows in {result.elapsed_ms}ms
            </span>
          )}
          {error && <span className="text-xs text-red-400">{error}</span>}
        </div>

        {/* Results */}
        {executeMutation.isPending && <LoadingSpinner />}

        {result && (
          <div className="flex-1 overflow-auto rounded-lg border border-surface-700">
            <table className="w-full text-xs">
              <thead className="sticky top-0 bg-surface-900">
                <tr>
                  {result.columns.map((col, i) => (
                    <th key={i} className="px-2 py-1.5 text-left font-medium text-gray-400">
                      {col.name} <span className="text-gray-600">({col.type})</span>
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {result.rows.map((row, ri) => (
                  <tr key={ri} className="border-t border-surface-700/30 hover:bg-surface-800/30">
                    {row.map((cell, ci) => (
                      <td key={ci} className="px-2 py-1 text-gray-300">
                        {cell == null ? <span className="text-gray-600">NULL</span> : String(cell)}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* Chart builder */}
        {result && result.columns.length >= 2 && (
          <Card className="shrink-0">
            <div className="mb-2 flex items-center gap-3">
              <span className="text-xs text-gray-500">Chart:</span>
              {(['none', 'bar', 'line', 'scatter'] as ChartType[]).map((ct) => (
                <button
                  key={ct}
                  onClick={() => setChartType(ct)}
                  className={`rounded px-2 py-0.5 text-xs ${chartType === ct ? 'bg-brand-600 text-white' : 'text-gray-400 hover:bg-surface-800'}`}
                >
                  {ct === 'none' ? 'Off' : ct}
                </button>
              ))}
              {chartType !== 'none' && (
                <>
                  <select value={xCol} onChange={(e) => setXCol(Number(e.target.value))} className="rounded border border-surface-700 bg-surface-900 px-1 py-0.5 text-xs text-gray-300" aria-label="X axis column">
                    {result.columns.map((c, i) => <option key={i} value={i}>{c.name}</option>)}
                  </select>
                  <span className="text-xs text-gray-600">→</span>
                  <select value={yCol} onChange={(e) => setYCol(Number(e.target.value))} className="rounded border border-surface-700 bg-surface-900 px-1 py-0.5 text-xs text-gray-300" aria-label="Y axis column">
                    {result.columns.map((c, i) => <option key={i} value={i}>{c.name}</option>)}
                  </select>
                </>
              )}
            </div>
            {chartType !== 'none' && chartData.length > 0 && (
              <ResponsiveContainer width="100%" height={250}>
                {chartType === 'bar' ? (
                  <BarChart data={chartData}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="label" tick={{ fill: '#6b7280', fontSize: 10 }} />
                    <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
                    <Bar dataKey="y" fill="#3b82f6" />
                  </BarChart>
                ) : chartType === 'line' ? (
                  <LineChart data={chartData}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="label" tick={{ fill: '#6b7280', fontSize: 10 }} />
                    <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
                    <Line type="monotone" dataKey="y" stroke="#3b82f6" dot={false} />
                  </LineChart>
                ) : (
                  <ScatterChart>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="x" tick={{ fill: '#6b7280', fontSize: 10 }} name={result.columns[xCol]?.name} />
                    <YAxis dataKey="y" tick={{ fill: '#6b7280', fontSize: 10 }} name={result.columns[yCol]?.name} />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
                    <Scatter data={chartData} fill="#3b82f6" />
                  </ScatterChart>
                )}
              </ResponsiveContainer>
            )}
          </Card>
        )}
      </div>
    </div>
  );
}
