/**
 * 数据库查看器页面。
 *
 * - 左侧：Schema → Table 层级树，异步加载
 * - 右侧上方：SQL 编辑器 + 执行按钮
 * - 右侧下方：列定义 / 查询结果 Table
 */

import React, { useEffect, useState, useCallback } from 'react';
import { Tree, Input, Button, Table, Space, message, Spin, Tag, Card, Typography, Tooltip } from 'antd';
import {
  PlayCircleOutlined, ReloadOutlined, TableOutlined,
  DatabaseOutlined, CopyOutlined,
} from '@ant-design/icons';
import type { DataNode, EventDataNode } from 'antd/es/tree';
import type { ColumnsType } from 'antd/es/table';
import {
  fetchSchemas, fetchTables, fetchColumns, executeQuery,
  type ColumnInfo, type QueryResult,
} from '../api/dbViewer';

const { TextArea } = Input;
const { Title, Text } = Typography;

const schemaKey = (schema: string) => `s::${schema}`;
const tableKey = (schema: string, table: string) => `t::${schema}::${table}`;

function parseTableKey(key: string): { schema: string; table: string } | null {
  if (!key.startsWith('t::')) return null;
  const parts = key.slice(3).split('::');
  if (parts.length !== 2) return null;
  return { schema: parts[0], table: parts[1] };
}

const DBViewer: React.FC = () => {
  const [treeData, setTreeData] = useState<DataNode[]>([]);
  const [loadingTree, setLoadingTree] = useState(false);
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [selectedTable, setSelectedTable] = useState<{ schema: string; table: string } | null>(null);
  const [columnData, setColumnData] = useState<ColumnInfo[]>([]);
  const [loadingColumns, setLoadingColumns] = useState(false);
  const [sql, setSql] = useState('');
  const [queryResult, setQueryResult] = useState<QueryResult | null>(null);
  const [loadingQuery, setLoadingQuery] = useState(false);

  const loadSchemas = useCallback(async () => {
    setLoadingTree(true);
    try {
      const schemas = await fetchSchemas();
      setTreeData(
        schemas.map((s) => ({
          title: s, key: schemaKey(s), icon: <DatabaseOutlined />, isLeaf: false,
        })),
      );
    } catch { message.error('加载 Schema 列表失败'); }
    finally { setLoadingTree(false); }
  }, []);

  useEffect(() => { loadSchemas(); }, [loadSchemas]);

  const onLoadData = async (node: EventDataNode<DataNode>) => {
    const key = node.key as string;
    if (!key.startsWith('s::')) return;
    if (node.children && node.children.length > 0) return;
    const schema = key.slice(3);
    try {
      const tables = await fetchTables(schema);
      const children: DataNode[] = tables.map((t) => ({
        title: (
          <Space size={4}>
            <span>{t.name}</span>
            <Text type="secondary" style={{ fontSize: 11 }}>({t.row_count.toLocaleString()})</Text>
          </Space>
        ),
        key: tableKey(schema, t.name), icon: <TableOutlined />, isLeaf: true,
      }));
      setTreeData((prev) => prev.map((n) => n.key === key ? { ...n, children } : n));
    } catch { message.error(`加载 ${schema} 的表列表失败`); }
  };

  const onSelectNode = async (_: React.Key[], info: { node: DataNode }) => {
    const key = info.node.key as string;
    const parsed = parseTableKey(key);
    if (!parsed) return;
    setSelectedTable(parsed);
    setLoadingColumns(true);
    setQueryResult(null);
    try {
      const cols = await fetchColumns(parsed.schema, parsed.table);
      setColumnData(cols);
      setSql(`SELECT * FROM ${parsed.schema}.${parsed.table} LIMIT 100;`);
    } catch { message.error('加载列定义失败'); setColumnData([]); }
    finally { setLoadingColumns(false); }
  };

  const handleExecute = async () => {
    const trimmed = sql.trim();
    if (!trimmed) { message.warning('请输入 SQL 语句'); return; }
    setLoadingQuery(true);
    try {
      const result = await executeQuery(trimmed);
      setQueryResult(result);
    } catch (err: unknown) {
      const axiosErr = err as { response?: { data?: { detail?: string } } };
      const msg = axiosErr.response?.data?.detail ?? (err instanceof Error ? err.message : '查询执行失败');
      message.error(msg);
      setQueryResult(null);
    } finally { setLoadingQuery(false); }
  };

  const handleCopySql = () => {
    navigator.clipboard.writeText(sql).then(() => message.success('已复制'));
  };

  const columnDefColumns: ColumnsType<ColumnInfo> = [
    { title: '列名', dataIndex: 'name', key: 'name', render: (v: string) => <code>{v}</code> },
    { title: '数据类型', dataIndex: 'data_type', key: 'data_type' },
    {
      title: '可空', dataIndex: 'is_nullable', key: 'is_nullable', width: 70, align: 'center',
      render: (v: boolean) => v ? <Tag color="orange">YES</Tag> : <Tag color="blue">NO</Tag>,
    },
    {
      title: '默认值', dataIndex: 'default_value', key: 'default_value',
      render: (v: string | null) => v != null ? <code style={{ fontSize: 12 }}>{v}</code> : <Text type="secondary">—</Text>,
    },
  ];

  const resultColumns: ColumnsType<Record<string, unknown>> = queryResult
    ? queryResult.columns.map((col, idx) => ({
        title: col, dataIndex: String(idx), key: col, ellipsis: true,
        render: (v: unknown) => {
          if (v === null || v === undefined) return <Text type="secondary">NULL</Text>;
          return String(v);
        },
      }))
    : [];

  const resultDataSource: Record<string, unknown>[] = queryResult
    ? queryResult.rows.map((row, rowIdx) => {
        const obj: Record<string, unknown> = { _key: rowIdx };
        row.forEach((cell, colIdx) => { obj[String(colIdx)] = cell; });
        return obj;
      })
    : [];

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: 'calc(100vh - 120px)' }}>
      <div style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <Title level={4} style={{ margin: 0 }}>
          <DatabaseOutlined style={{ marginRight: 8 }} />
          数据库查看器
        </Title>
        {selectedTable && (
          <Tag color="blue">{selectedTable.schema}.{selectedTable.table}</Tag>
        )}
      </div>

      <div style={{ display: 'flex', flex: 1, gap: 12, minHeight: 0 }}>
        {/* 左侧树 */}
        <Card
          size="small"
          title="Schema / 表"
          extra={<Button size="small" icon={<ReloadOutlined />} onClick={loadSchemas} loading={loadingTree} />}
          style={{ width: 260, minWidth: 260, display: 'flex', flexDirection: 'column' }}
          styles={{ body: { flex: 1, overflow: 'auto', padding: '8px 12px' } }}
        >
          <Spin spinning={loadingTree}>
            <Tree
              showIcon treeData={treeData} loadData={onLoadData}
              expandedKeys={expandedKeys}
              onExpand={(keys) => setExpandedKeys(keys)}
              onSelect={onSelectNode}
            />
          </Spin>
        </Card>

        {/* 右侧 */}
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
          {/* SQL 编辑器 */}
          <Card size="small" style={{ marginBottom: 12 }} styles={{ body: { padding: '8px 12px' } }}>
            <TextArea
              rows={5} value={sql} onChange={(e) => setSql(e.target.value)}
              placeholder="输入 SQL 查询语句…"
              style={{ fontFamily: "'Cascadia Code', 'Fira Code', Consolas, monospace", fontSize: 13, marginBottom: 8 }}
              onKeyDown={(e) => { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); handleExecute(); } }}
            />
            <Space>
              <Button type="primary" icon={<PlayCircleOutlined />} onClick={handleExecute} loading={loadingQuery}>
                执行 <Text type="secondary" style={{ fontSize: 11, marginLeft: 4 }}>(Ctrl+Enter)</Text>
              </Button>
              <Tooltip title="复制 SQL">
                <Button icon={<CopyOutlined />} onClick={handleCopySql} />
              </Tooltip>
            </Space>
          </Card>

          {/* 结果区域 */}
          <Card size="small" style={{ flex: 1, display: 'flex', flexDirection: 'column' }}
            styles={{ body: { flex: 1, overflow: 'auto', padding: '8px 12px' } }}
          >
            {queryResult ? (
              <>
                <div style={{ marginBottom: 8 }}>
                  <Text type="secondary">查询返回 {queryResult.row_count} 行</Text>
                </div>
                <Table<Record<string, unknown>>
                  rowKey="_key" columns={resultColumns} dataSource={resultDataSource}
                  pagination={{ pageSize: 50, showSizeChanger: false, showTotal: (t) => `共 ${t} 行` }}
                  size="small" scroll={{ x: 'max-content' }} bordered
                />
              </>
            ) : selectedTable ? (
              <>
                <div style={{ marginBottom: 8 }}>
                  <Text strong>{selectedTable.schema}.{selectedTable.table}</Text>
                  <Text type="secondary" style={{ marginLeft: 8 }}>列定义</Text>
                </div>
                <Table<ColumnInfo>
                  rowKey="name" columns={columnDefColumns} dataSource={columnData}
                  loading={loadingColumns} pagination={false} size="small" bordered
                />
              </>
            ) : (
              <div style={{ color: '#bbb', textAlign: 'center', marginTop: 60 }}>
                在左侧选择一张表查看列定义，或输入 SQL 执行查询
              </div>
            )}
          </Card>
        </div>
      </div>
    </div>
  );
};

export default DBViewer;
