import React from 'react';
import { Button, Input, Space, Tag, Typography } from 'antd';

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

type JsonValue = any;

type VideoPromptSchemaEditorProps = {
  value: Record<string, JsonValue>;
  onChange: (nextValue: Record<string, JsonValue>) => void;
};

const LOCKED_TOP_LEVEL_KEYS = new Set([
  'schema_version',
  'schema_usage',
  '动态时间规划',
  '输出规格限制',
  '合规控制',
  '质量控制',
]);

const HIDDEN_TOP_LEVEL_KEYS = new Set([
  'schemaUsage',
  'schemaVersion',
  '输出规格限制',
]);

const LOCKED_FRAME_KEYS = new Set([
  '视频时长',
  '视频比例',
  '清晰度',
  '帧率',
  '推荐分辨率',
]);

const EDITABLE_FRAME_KEYS = new Set([
  '主体描述',
  '主体数量',
  '主体位置',
  '主体占比',
  '场景描述',
  '构图方式',
  '画面风格',
  '光影色彩',
]);

const EDITABLE_FINAL_PROMPT_KEYS = new Set([
  '主提示词',
  '动作提示词',
  '镜头提示词',
  '字幕提示词',
  '音频提示词',
  '风格提示词',
  '负面提示词',
]);

function clonePlain<T>(value: T): T {
  return value === undefined ? value : JSON.parse(JSON.stringify(value));
}

function pathIncludes(path: Array<string | number>, key: string): boolean {
  return path.some((item) => String(item) === key);
}

function getPathValue(root: JsonValue, path: Array<string | number>): JsonValue {
  let current = root;
  for (const key of path) {
    if (current === undefined || current === null) return undefined;
    current = current[key as keyof typeof current];
  }
  return current;
}

function setPathValue(root: JsonValue, path: Array<string | number>, value: JsonValue): JsonValue {
  const next = clonePlain(root);
  let current = next;
  for (let index = 0; index < path.length - 1; index += 1) {
    current = current[path[index] as keyof typeof current];
  }
  current[path[path.length - 1] as keyof typeof current] = value;
  return next;
}

function removeArrayItem(root: JsonValue, path: Array<string | number>, index: number): JsonValue {
  const arrayValue = getPathValue(root, path);
  if (!Array.isArray(arrayValue)) return root;
  return setPathValue(root, path, arrayValue.filter((_, itemIndex) => itemIndex !== index));
}

function addArrayItem(root: JsonValue, path: Array<string | number>, sampleValue: JsonValue): JsonValue {
  const arrayValue = getPathValue(root, path);
  if (!Array.isArray(arrayValue)) return root;
  const nextItem = typeof sampleValue === 'object' && sampleValue !== null ? clonePlain(sampleValue) : '';
  return setPathValue(root, path, [...arrayValue, nextItem]);
}

function stringifyReadonly(value: JsonValue): string {
  if (value === null || value === undefined) return '';
  if (typeof value === 'object') return JSON.stringify(value, null, 2);
  return String(value);
}

function shouldUseTextArea(value: JsonValue): boolean {
  const text = stringifyReadonly(value);
  return text.length > 40 || text.includes('\n') || text.includes('，') || text.includes('。');
}

function isLockedPath(path: Array<string | number>): boolean {
  const rootKey = String(path[0] ?? '');
  const currentKey = String(path[path.length - 1] ?? '');

  if (LOCKED_TOP_LEVEL_KEYS.has(rootKey)) return true;
  if (rootKey === '画面属性') {
    if (LOCKED_FRAME_KEYS.has(currentKey)) return true;
    if (!EDITABLE_FRAME_KEYS.has(currentKey)) return false;
  }
  if (rootKey === '最终提示词' && path.length === 2) {
    return !EDITABLE_FINAL_PROMPT_KEYS.has(currentKey);
  }
  if ((rootKey === '动作流程' || rootKey === '镜头流程') && currentKey === '时间段') {
    return true;
  }

  return false;
}

function canAddOrRemoveArray(path: Array<string | number>): boolean {
  const rootKey = String(path[0] ?? '');
  if (LOCKED_TOP_LEVEL_KEYS.has(rootKey)) return false;
  if (rootKey === '动作流程' || rootKey === '镜头流程') return false;
  return true;
}

function fieldTitle(key: string | number): string {
  return typeof key === 'number' ? `第 ${key + 1} 项` : key;
}

function ReadonlyBlock({ value }: { value: JsonValue }) {
  const text = stringifyReadonly(value);
  return shouldUseTextArea(value) ? (
    <TextArea value={text} rows={Math.min(6, Math.max(2, Math.ceil(text.length / 42)))} disabled style={{ borderRadius: 8, color: '#64748b' }} />
  ) : (
    <Input value={text} disabled style={{ borderRadius: 8, color: '#64748b' }} />
  );
}

function EditableInput({ value, onChange }: { value: JsonValue; onChange: (nextValue: JsonValue) => void }) {
  const text = stringifyReadonly(value);
  if (shouldUseTextArea(value)) {
    return (
      <TextArea
        value={text}
        onChange={(event) => onChange(event.target.value)}
        rows={Math.min(8, Math.max(3, Math.ceil(text.length / 42)))}
        style={{ borderRadius: 8 }}
      />
    );
  }

  return <Input value={text} onChange={(event) => onChange(event.target.value)} style={{ borderRadius: 8 }} />;
}

const VideoPromptSchemaEditor: React.FC<VideoPromptSchemaEditorProps> = ({ value, onChange }) => {
  const safeValue = value && typeof value === 'object' ? value : {};

  const updatePath = (path: Array<string | number>, nextValue: JsonValue) => {
    onChange(setPathValue(safeValue, path, nextValue));
  };

  const renderNode = (key: string | number, nodeValue: JsonValue, path: Array<string | number>, depth = 0): React.ReactNode => {
    const locked = isLockedPath(path);
    const rootKey = String(path[0] ?? '');

    if (Array.isArray(nodeValue)) {
      const editableArray = !locked && canAddOrRemoveArray(path);
      const sample = nodeValue.find((item) => item !== undefined) ?? '';
      return (
        <div key={path.join('.')} style={{ marginBottom: 18 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
            <Space>
              <Text strong style={{ color: '#334155', fontSize: 13 }}>{fieldTitle(key)}</Text>
              {/* {!editableArray && <Tag color="default">锁定结构</Tag>} */}
            </Space>
            {editableArray && (
              <Button size="small" type="link" onClick={() => onChange(addArrayItem(safeValue, path, sample))}>
                + 添加
              </Button>
            )}
          </div>

          <div style={{ border: '1px solid #e5e7eb', borderRadius: 10, padding: 12, background: locked ? '#f8fafc' : '#fff' }}>
            {nodeValue.length === 0 ? (
              <Text style={{ color: '#94a3b8', fontSize: 12 }}>暂无内容</Text>
            ) : (
              nodeValue.map((item, index) => (
                <div key={`${path.join('.')}.${index}`} style={{ marginBottom: index === nodeValue.length - 1 ? 0 : 12 }}>
                  <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
                    <Text style={{ color: '#94a3b8', fontSize: 12, marginTop: 7, minWidth: 28 }}>{index + 1}.</Text>
                    <div style={{ flex: 1 }}>
                      {typeof item === 'object' && item !== null ? (
                        renderObjectFields(item, [...path, index], depth + 1)
                      ) : locked ? (
                        <ReadonlyBlock value={item} />
                      ) : (
                        <EditableInput value={item} onChange={(nextText) => updatePath([...path, index], nextText)} />
                      )}
                    </div>
                    {editableArray && (
                      <Button size="small" type="text" danger onClick={() => onChange(removeArrayItem(safeValue, path, index))}>
                        删除
                      </Button>
                    )}
                  </div>
                </div>
              ))
            )}
          </div>

          {/* {(rootKey === '动作流程' || rootKey === '镜头流程') && (
            <Text style={{ display: 'block', marginTop: 6, color: '#94a3b8', fontSize: 12 }}>
              时间段和条目数量由后端锁定，只允许编辑每段里的动作、镜头、说明等内容。
            </Text>
          )} */}
        </div>
      );
    }

    if (typeof nodeValue === 'object' && nodeValue !== null) {
      const lockedSection = locked || LOCKED_TOP_LEVEL_KEYS.has(String(key));
      return (
        <div key={path.join('.')} style={{ marginBottom: 18 }}>
          <Space style={{ marginBottom: 8 }}>
            <Text strong style={{ color: '#334155', fontSize: 13 }}>{fieldTitle(key)}</Text>
            {/* {lockedSection && <Tag color="default">只读</Tag>} */}
          </Space>
          <div
            style={{
              borderLeft: depth === 0 ? '3px solid #6366f1' : '2px solid #e2e8f0',
              paddingLeft: 12,
              marginLeft: 4,
              background: lockedSection ? '#f8fafc' : 'transparent',
            }}
          >
            {renderObjectFields(nodeValue, path, depth + 1)}
          </div>
        </div>
      );
    }

    return (
      <div key={path.join('.')} style={{ marginBottom: 12 }}>
        <Space style={{ marginBottom: 4 }}>
          <Text style={{ color: '#64748b', fontSize: 12 }}>{fieldTitle(key)}</Text>
          {/* {locked && <Tag color="default">只读12312</Tag>} */}
        </Space>
        {locked ? (
          <ReadonlyBlock value={nodeValue} />
          // <></>
        ) : (
          <EditableInput value={nodeValue} onChange={(nextText) => updatePath(path, nextText)} />
        )}
      </div>
    );
  };

  const renderObjectFields = (objectValue: Record<string, JsonValue>, parentPath: Array<string | number>, depth = 0): React.ReactNode => {
    return Object.entries(objectValue).map(([childKey, childValue]) => renderNode(childKey, childValue, [...parentPath, childKey], depth));
  };

  return (
    <div>
      {/* <div style={{ marginBottom: 14, padding: 12, borderRadius: 10, background: '#f8fafc', color: '#64748b', fontSize: 13, lineHeight: 1.7 }}>
        视频时长、比例、清晰度、帧率、推荐分辨率、动态时间规划、输出规格、质量控制、合规控制、schema 协议字段为只读；动作/镜头流程保留原时间段和条目数量，只允许编辑内容描述。
      </div> */}
      {Object.entries(safeValue)
        .filter(([key]) => !HIDDEN_TOP_LEVEL_KEYS.has(key))
        .map(([key, childValue]) => renderNode(key, childValue, [key]))}
    </div>
  );
};

export default VideoPromptSchemaEditor;
