import { ContentItem, LensType, SimpleCharacter, TagValueObject } from '../domain/valueObject';
import { ScriptRoleEntity } from '../domain/Entities';

// 定义高亮属性接口
interface HighlightAttributes {
  text: string;
  color: string;
}

// 定义文本节点接口
interface TextNode {
  type: 'text';
  text: string;
}

// 定义角色标记节点接口
interface CharacterTokenNode {
  type: 'characterToken';
  attrs: ScriptRoleEntity;
}

// 定义高亮节点接口
interface HighlightNode {
  type: 'highlightText';
  attrs: HighlightAttributes;
}

// 定义只读文本节点接口
interface ReadonlyTextNode {
  type: 'readonlyText';
  attrs: {
    text: string;
  };
}

// 定义内容节点类型（文本或角色标记）
type ContentNode = TextNode | CharacterTokenNode | HighlightNode | ReadonlyTextNode;

// 定义段落接口
interface Paragraph {
  type: 'paragraph';
  content: ContentNode[];
}

// 定义shot 接口
interface Shot {
  name: string;
  shotDescContent: Paragraph[];
  shotDialogsContent: Paragraph[];
}

export class TextToShotAdapter {
  /**
   * 解析文本，识别角色并转换为节点数组
   * @param text 要解析的文本
   * @param roles 角色列表
   * @returns ContentNode[] 节点数组
   */
  public static parseText(text: string, roles: ScriptRoleEntity[]): ContentNode[] {
    const nodes: ContentNode[] = [];
    let currentText = text;

    // 按角色名称长度降序排序，避免短名称匹配到长名称的一部分
    // 既要兼容 每个单词 首字母大写 其余小写、还要兼容 全部大写
    const sortedRoles = [...roles].sort((a, b) => b.name.length - a.name.length).map(role => ({
      ...role,
      match_name: role.name.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ') + ' [' + role.id + ']'
    })).concat([...roles].map(role => ({
      ...role,
      match_name: role.name.toUpperCase() + ' [' + role.id + ']'
    })));

    console.log('shots-匹配角色', text, sortedRoles);


    while (currentText.length > 0) {
      let matchFound = false;
      
      // 尝试匹配角色
      for (const role of sortedRoles) {
        if (currentText.startsWith(role.match_name)) {
          // 如果当前文本以角色名开头
          if (currentText.length > role.match_name.length) {
            // 添加角色标记节点
            nodes.push({
              type: 'characterToken',
              attrs: {
                ...role
              }
            });
            // 移除已处理的角色名
            currentText = currentText.slice(role.match_name.length);
            matchFound = true;
            break;
          }
        }
      }

      if (!matchFound) {
        // 如果没有找到角色匹配，处理普通文本
        // 查找下一个可能的角色名位置
        let nextRoleIndex = currentText.length;
        for (const role of sortedRoles) {
          const index = currentText.indexOf(role.match_name);
          if (index !== -1 && index < nextRoleIndex) {
            nextRoleIndex = index;
          }
        }

        // 添加文本节点
        const textContent = currentText.slice(0, nextRoleIndex);
        if (textContent) {
          nodes.push({
            type: 'text',
            text: textContent
          });
        }
        // 移除已处理的文本
        currentText = currentText.slice(nextRoleIndex);
      }
    }

    return nodes;
  }
  /**
   * 解析高亮文本，识别tag并转换为节点数组
   * @param text 要解析的文本
   * @param tags 标签列表
   * @returns ContentNode[] 节点数组
   */
  public static parseHighlight(text: string, tags: TagValueObject[]): ContentNode[] {
    const nodes: ContentNode[] = [];
    let currentText = text;
    
    // 1. 确保 tags 是有效的数组
    if (!Array.isArray(tags)) {
      console.warn('Invalid tags:', tags);
      return [{ type: 'text', text: currentText }];
    }
  
    // 2. 恢复排序逻辑，并添加安全检查
    const sortedTags = [...tags]
      .filter(tag => tag && tag.content) // 过滤无效的 tag
      .sort((a, b) => String(b.content).length - String(a.content).length);
  
    // 3. 添加安全检查，防止无限循环
    let iterationCount = 0;
    const MAX_ITERATIONS = 1000; // 设置一个合理的最大迭代次数
  
    while (currentText.length > 0 && iterationCount < MAX_ITERATIONS) {
      iterationCount++;
      let matchFound = false;
      
      for (const tag of sortedTags) {
        const tagContent = String(tag.content);
        if (currentText.startsWith(tagContent)) {
          if (currentText.length > tagContent.length) {
            nodes.push({
              type: 'highlightText',
              attrs: {
                text: tagContent,
                color: tag?.color || 'yellow'
              }
            });
            currentText = currentText.slice(tagContent.length);
            matchFound = true;
            break;
          }
        }
      }
  
      if (!matchFound) {
        let nextTagIndex = currentText.length;
        for (const tag of sortedTags) {
          const index = currentText.indexOf(String(tag.content));
          if (index !== -1 && index < nextTagIndex) {
            nextTagIndex = index;
          }
        }
  
        const textContent = currentText.slice(0, nextTagIndex);
        if (textContent) {
          nodes.push({
            type: 'text',
            text: textContent
          });
        }
        currentText = currentText.slice(nextTagIndex);
      }
    }
  
    // 4. 如果达到最大迭代次数，处理剩余文本
    if (currentText.length > 0) {
      nodes.push({
        type: 'text',
        text: currentText
      });
    }
  
    return nodes;
  }
  private readonly ShotData: Shot;
  constructor(shotData: Shot) {
    this.ShotData = shotData;
  }

  toShot() {
    return this.ShotData;
  }

  /**
   * 将 LensType 转换为 Paragraph 格式
   * @param lensType LensType 实例
   * @returns Paragraph 格式的数据
   */
  public static fromLensType(lensType: LensType, roles: ScriptRoleEntity[]): Shot {
    const shotDescContent: Paragraph[] = [];
    const shotDialogsContent: Paragraph[] = [];

    // 处理镜头描述 通过roles name 匹配镜头描述中出现的角色 并添加到shotDescContent
    if (lensType.script) {
      const descNodes = TextToShotAdapter.parseText(lensType.script, roles);
      shotDescContent.push({
        type: 'paragraph',
        content: descNodes
      });
    }

    // 处理对话内容 通过roles name 匹配对话内容中出现的角色 并添加到shotDialogsContent
    lensType.content.forEach(item => {
      const dialogNodes = TextToShotAdapter.parseText(item.content, roles);
      
      // 确保对话内容以角色标记开始 角色名都大写再匹配
      const roleMatch = roles.find(role => role.name.toUpperCase().includes(item.roleName.toUpperCase()));
      if (roleMatch) {
        const dialogContent: Paragraph = {
          type: 'paragraph',
          content: [{
            type: 'characterToken',
            attrs: {
              ...roleMatch
            }},
            {
              type: 'readonlyText',
              attrs: {
                text: '：'
              }
            },
            ...dialogNodes
          ]
        };

        shotDialogsContent.push(dialogContent);
      }
    });

    return {
      name: lensType.name,
      shotDescContent,
      shotDialogsContent
    };
  }

  /**
   * 将 Paragraph 转换为 LensType 格式
   * @param paragraphData Paragraph 格式的数据
   * @returns LensType 实例
   */
  /**
   * 将 Shot 格式转换为 LensType 格式
   * @param shotData Shot 格式的数据
   * @returns LensType 实例
   */
  public static toLensType(shotData: Shot): LensType {
    const content: ContentItem[] = [];
    let currentScript = '';

    // 处理镜头描述
    if (shotData.shotDescContent.length > 0) {
      // 合并所有描述段落的文本内容
      shotData.shotDescContent.forEach(paragraph => {
        if (paragraph.content) {
          paragraph.content.forEach(node => {
            if (node.type === 'text') {
              currentScript += node.text;
            }
            if (node.type === 'characterToken') {
              currentScript = currentScript + node.attrs.name + ' [' + node.attrs.id + ']';
            }
          });
        }
      });
    }

    // 处理对话内容
    shotData.shotDialogsContent.forEach(paragraph => {
      let dialogRoleName = '';
      let dialogContent = '';
      let firstFindRole = false;

      // 遍历段落内容
      if (paragraph.content) {
        paragraph.content.forEach((node, index) => {
          if (node.type === 'characterToken') {
            // 记录说话角色的名称
            if (!firstFindRole) {
              dialogRoleName = node.attrs.name + ' [' + node.attrs.id + ']';
              firstFindRole = true;
            } else {
              dialogContent += node.attrs.name + ' [' + node.attrs.id + ']';
            }
          } else if (node.type === 'text') {
            // 累积对话内容
            dialogContent += node.text;
          }
        });
      }

      // 如果有角色名和对话内容，添加到结果中
      if (dialogRoleName && dialogContent) {
        content.push({
          roleName: dialogRoleName,
          content: dialogContent.trim()
        });
      }
    });

    return new LensType(
      shotData.name, // 使用 Shot 中的 name
      currentScript.trim(),
      content
    );
  }

  public static fromTextToRole(description: string, tags: TagValueObject[]): Paragraph[] {
    const paragraph: Paragraph = {
      type: 'paragraph',
      content: []
    };
    const highlightNodes = TextToShotAdapter.parseHighlight(description, tags);
    paragraph.content.push(...highlightNodes);
    return [paragraph];
  }
  public static fromRoleToText(paragraphs: Paragraph[]): string {
    let text = '';
    paragraphs.forEach(paragraph => {
      if (paragraph?.content) {
        paragraph.content.forEach(node => {
          if (node.type === 'highlightText') {
            text += node.attrs.text;
          } else if (node.type === 'text') {
            text += node.text;
          } else if (node.type === 'characterToken') {
            text += node.attrs.name + ' ' + node.attrs.id;
          }
        });
      }
    });
    return text;
  }
}