import React from 'react';
import { Card, Collapse, Descriptions, Empty, Space, Table, Tag, Typography } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { JsonBlock } from './JsonCollapse';
import type {
  VideoPromptSchemaFieldConfig,
  VideoPromptSchemaSectionConfig,
} from '../../../utils/videoPromptSchema';
import {
  hasSchemaConfigSnapshot,
  inferSchemaSections,
  normalizeSchemaSections,
  stringifySchemaValue,
} from '../../../utils/videoPromptSchema';

const isRecord = (value: unknown): value is Record<string, unknown> => !!value && typeof value === 'object' && !Array.isArray(value);
const isLongText = (value: unknown): boolean => typeof value === 'string' && value.length > 80;

const renderValue = (value: unknown): React.ReactNode => {
  if (value === null || value === undefined || value === '') return <Typography.Text type="secondary">-</Typography.Text>;
  if (typeof value === 'boolean') return value ? '是' : '否';
  if (typeof value === 'number') return value;
  if (typeof value === 'string') {
    return <Typography.Paragraph style={{ marginBottom: 0, whiteSpace: 'pre-wrap' }}>{value}</Typography.Paragraph>;
  }
  return <JsonBlock value={value} maxHeight={220} />;
};

const tagOfEditable = (editable?: boolean) => editable ? <Tag color="processing">可编辑</Tag> : <Tag color="default">只读</Tag>;

const readSectionValue = (schema: Record<string, any>, key: string): unknown => schema[key];

const renderObjectSection = (schema: Record<string, any>, section: VideoPromptSchemaSectionConfig): React.ReactNode => {
  const value = readSectionValue(schema, section.key);
  if (!isRecord(value)) return <JsonBlock value={value ?? {}} maxHeight={220} />;
  const fields = section.children.filter((field) => field.enabled);
  if (!fields.length) return <JsonBlock value={value} maxHeight={220} />;

  return (
    <Descriptions size="small" column={2} bordered>
      {fields.map((field) => (
        <Descriptions.Item key={field.key} label={<Space size={4}>{field.label}{tagOfEditable(field.editable)}</Space>} span={isLongText(value[field.key]) || isRecord(value[field.key]) || Array.isArray(value[field.key]) ? 2 : 1}>
          {renderValue(value[field.key])}
        </Descriptions.Item>
      ))}
    </Descriptions>
  );
};

const buildFlowFields = (section: VideoPromptSchemaSectionConfig, rows: Record<string, unknown>[]): VideoPromptSchemaFieldConfig[] => {
  const configured = section.itemFields.filter((field) => field.enabled);
  if (configured.length) {
    return [{ key: '时间段', label: '时间段', enabled: true, editable: false }, ...configured];
  }
  const inferred = Array.from(new Set(rows.flatMap((row) => Object.keys(row))));
  return inferred.map((key) => ({ key, label: key, enabled: true, editable: false }));
};

const renderFlowSection = (schema: Record<string, any>, section: VideoPromptSchemaSectionConfig): React.ReactNode => {
  const value = readSectionValue(schema, section.key);
  if (!Array.isArray(value) || !value.every(isRecord)) return <JsonBlock value={value ?? []} maxHeight={260} />;
  const rows = value as Record<string, unknown>[];
  const fields = buildFlowFields(section, rows);
  const columns: ColumnsType<Record<string, unknown>> = fields.map((field) => ({
    title: <Space size={4}>{field.label}{tagOfEditable(field.editable)}</Space>,
    dataIndex: field.key,
    key: field.key,
    width: isLongText(rows.find((row) => row[field.key])?.[field.key]) ? 320 : 160,
    render: (cell: unknown) => renderValue(cell),
  }));

  return (
    <Table
      size="small"
      rowKey={(_, index) => `${section.key}-${index}`}
      columns={columns}
      dataSource={rows}
      pagination={false}
      scroll={{ x: Math.max(900, fields.length * 180) }}
      tableLayout="fixed"
    />
  );
};

const renderPrimitiveSection = (schema: Record<string, any>, section: VideoPromptSchemaSectionConfig): React.ReactNode => {
  const value = readSectionValue(schema, section.key);
  return renderValue(value);
};

interface VideoPromptSchemaViewerProps {
  schema?: Record<string, any> | null;
  finalPrompt?: string | null;
  schemaConfigSnapshot?: Record<string, any> | null;
  schemaConfigSource?: string | null;
  schemaConfigVersion?: string | null;
  schemaConfigIsFallback?: boolean | null;
}

const VideoPromptSchemaViewer: React.FC<VideoPromptSchemaViewerProps> = ({
  schema,
  finalPrompt,
  schemaConfigSnapshot,
  schemaConfigSource,
  schemaConfigVersion,
  schemaConfigIsFallback,
}) => {
  const hasSchema = !!schema && Object.keys(schema).length > 0;
  if (!hasSchema && !finalPrompt) {
    return <Empty description="暂无视频提词 schema" />;
  }

  const safeSchema = hasSchema ? schema as Record<string, any> : {};
  const hasSnapshot = hasSchemaConfigSnapshot(schemaConfigSnapshot);
  const sections = hasSnapshot ? normalizeSchemaSections(schemaConfigSnapshot) : inferSchemaSections(safeSchema);
  const schemaItems = sections
    .filter((section) => section.key in safeSchema)
    .map((section) => ({
      key: section.key,
      label: (
        <Space size={8} wrap>
          <span>{section.label}</span>
          {tagOfEditable(section.editable)}
          {!hasSnapshot ? <Tag color="warning">管理后台兜底展示</Tag> : null}
        </Space>
      ),
      children: section.type === 'object'
        ? renderObjectSection(safeSchema, section)
        : section.type === 'flow'
          ? renderFlowSection(safeSchema, section)
          : renderPrimitiveSection(safeSchema, section),
    }));

  return (
    <Space direction="vertical" size={12} style={{ width: '100%' }}>
      <Card size="small" title="Schema 配置来源">
        <Descriptions size="small" column={3} bordered>
          <Descriptions.Item label="来源">{schemaConfigSource || schemaConfigSnapshot?.source || (hasSnapshot ? '-' : 'viewer_fallback')}</Descriptions.Item>
          <Descriptions.Item label="版本">{schemaConfigVersion || schemaConfigSnapshot?.version || '-'}</Descriptions.Item>
          <Descriptions.Item label="历史兜底">{schemaConfigIsFallback || !hasSnapshot ? <Tag color="warning">是</Tag> : <Tag color="success">否</Tag>}</Descriptions.Item>
        </Descriptions>
      </Card>

      {finalPrompt ? (
        <Card size="small" title="最终视频提示词">
          <Typography.Paragraph style={{ whiteSpace: 'pre-wrap', marginBottom: 0 }}>{finalPrompt}</Typography.Paragraph>
        </Card>
      ) : null}

      {schemaItems.length ? (
        <Collapse size="small" items={schemaItems} />
      ) : hasSchema ? (
        <Card size="small" title="视频提词 Schema">
          <JsonBlock value={safeSchema} maxHeight={360} />
        </Card>
      ) : null}

      {hasSchema ? (
        <Collapse
          size="small"
          items={[{
            key: 'raw_schema',
            label: '原始 JSON / 历史脏字段排查',
            children: <JsonBlock value={safeSchema} maxHeight={420} />,
          }]}
        />
      ) : null}
    </Space>
  );
};

export default VideoPromptSchemaViewer;
