import { diff_match_patch as DiffMatchPatch } from 'diff-match-patch';
import { getDiffType, renderLines } from './utils';

export interface DiffsProps {
  name?: string;
  type?: string;
  id?: number;
  key?: string;
  last?: string;
  next?: string;
}

export interface isDiffsProps {
  chWords: boolean;
  lineNum: number;
  type: string;
  value: string;
}

export interface DiffGroupProps {
  name: string;
  value: number;
  key: string;
  cards: Array<DiffsProps>;
}

const Compare = {
  // 对比转换回html
  changeStrToHtml(str: string) {
    let str1 = str
      .replace(/\&para\;\<br\>/g, '\n')
      .replace(/\&gt\;/g, '>')
      .replace(/\&lt\;/g, '<')
      .replace(/\&amp\;/g, '&');
    // .replace(/list\-style\:none\;/, '')
    // .replace(/text\-decoration\:none\;/, '');
    return str1.substring(6, str1.length - 7);
  },
  diff_prettyHtml(diffs: any) {
    var html = [];
    var pattern_amp = /&/g;
    var pattern_lt = /</g;
    var pattern_gt = />/g;
    var pattern_para = /\n/g;
    for (var x = 0; x < diffs.length; x++) {
      var op = diffs[x][0]; // Operation (insert, delete, equal)
      var data = diffs[x][1]; // Text of change.
      var text = data
        .replace(pattern_amp, '&amp;')
        .replace(pattern_lt, '&lt;')
        .replace(pattern_gt, '&gt;')
        .replace(pattern_para, '&para;<br>');
      html[x] = text;
      // switch (op) {
      //   case DIFF_INSERT:
      //     html[x] = '<ins style="background:#e6ffe6;">' + text + '</ins>';
      //     break;
      //   case DIFF_DELETE:
      //     html[x] = '<del style="background:#ffe6e6;">' + text + '</del>';
      //     break;
      //   case DIFF_EQUAL:
      //     html[x] = '<span>' + text + '</span>';
      //     break;
      // }
    }
    // console.log(html, 'yyyyyyyyyyyyyyy')
    return html.join('');
  },
  // 合并函数不带颜色
  concatHTMLWithoutColor(
    prev: string | undefined,
    current: string | undefined,
  ) {
    var dmp = new DiffMatchPatch();
    var d = dmp.diff_main(prev as string, current as string);
    let html = '';
    d.forEach(str => {
      html += str[1];
    });
    return html;
  },
  // 合并函数
  concatHTML(prev: string | undefined, current: string | undefined) {
    var dmp = new DiffMatchPatch();
    var d = dmp.diff_main(prev as string, current as string);

    dmp.diff_cleanupSemantic(d);
    var ds = dmp.diff_prettyHtml(d);

    // 拿到对比完之后的数组
    let html = this.changeStrToHtml(ds);
    return html;
  },
  // 两屏对比函数
  diffScreens(
    prev: string | undefined,
    current: string | undefined,
    notTag: Array<string> = [],
  ) {
    const dmp = new DiffMatchPatch();
    const diff = dmp.diff_main(prev as string, current as string);
    dmp.diff_cleanupSemantic(diff);

    let word = diff
      .filter(result => getDiffType(result[0]) !== 'removed')
      .map(result => {
        let t = '';
        // 字符串内是否带a标签和p标签
        let isE = false;

        notTag.forEach((t: string) => {
          if (result[1].includes(t)) {
            isE = true;
          }
        });

        if (getDiffType(result[0]) === 'added' && !isE) {
          t = `<span class='modified'>${result[1]}</span>`;
        } else {
          t = result[1];
        }
        return t;
      })
      .join('');

    return word;
  },
  // 两屏对比塞入颜色
  compareHTML(html1: string, html2: string, notTag: Array<string> | any = []) {
    // console.log(Htmlj1.value, Htmlj2.value, 'kkkkkkk')
    const result = renderLines('split', html1, html2);
    // console.log(result, '两屏对比结果');
    let isDiffs: Array<Array<isDiffsProps>> = [];

    let newHTML1 = '';
    let newHTML2 = '';
    result.forEach((res, index) => {
      let left = res[0];
      let id = `pos${index}`;
      if (!left.chkWords) {
        newHTML1 += `<span class="vue-diff-cell-${left.type} ${id}">${left.value}</span>`;
      } else {
        let diffText = Compare.diffScreens(res[1].value, left.value, notTag);
        // console.log(diffText, '对比出不一样的两行数据');
        newHTML1 += `<span class="vue-diff-cell-${left.type} ${id}" id="diff-left-${index}">${diffText}</span>`;

        // 给左边标记添加事件
        // setTimeout(() => {
        //   let dom: any = document.getElementById(`diff-left-${index}`)
        //   console.dir(dom)
        //   dom.onclick = function (e: any) {
        //     console.log(diffText)
        //   }
        // }, 1000)
      }

      let right = res[0];
      if (!right.chkWords) {
        newHTML2 += `<span class="vue-diff-cell-${right.type} ${id}">${right.value}</span>`;
      } else {
        let diffText = Compare.diffScreens(right.value, res[1].value, notTag);
        newHTML2 += `<span class="vue-diff-cell-added ${id}" id="diff-right-${index}">${diffText}</span>`;

        // 给右边标记添加事件
        // setTimeout(() => {
        //   let dom: any = document.getElementById(`diff-right-${index}`)
        //   console.dir(dom)
        //   dom.onclick = function (e: any) {
        //     console.log(diffText)
        //   }
        // }, 1000)
      }

      // 计算不同的地方
      let i0 = res[0];
      let i1 = res[1];
      if (i0.type !== i1.type) {
        const d: any = this.computeTypes(res, index, id);
        isDiffs = isDiffs.concat(d);
      }
    });

    const Diffs: any = this.uniqText(isDiffs);

    return { newHTML1, newHTML2, Diffs };
  },
  // 去重
  uniqText(isDiffs: Array<Array<isDiffsProps>>) {
    let textArr: Array<string> = [];
    isDiffs.forEach(item => {
      let str = JSON.stringify(item);
      if (!textArr.includes(str)) {
        textArr.push(str);
      }
    });
    let newArr: Array<DiffsProps> = [];
    textArr.forEach(str => {
      newArr.push(JSON.parse(str));
    });

    let add = newArr.filter(item => item.type === 'add');
    let remove = newArr.filter(item => item.type === 'remove');
    let edit = newArr.filter(item => item.type === 'edit');

    return {
      Diffs: newArr,
      DiffsCount: [
        {
          name: '全部',
          value: newArr.length,
          key: 'all',
          cards: newArr as Array<DiffsProps>,
        },
        {
          name: '删除',
          value: remove.length,
          key: 'remove',
          cards: remove as Array<DiffsProps>,
        },
        {
          name: '新增',
          value: add.length,
          key: 'add',
          cards: add as Array<DiffsProps>,
        },
        {
          name: '修改',
          value: edit.length,
          key: 'edit',
          cards: edit as Array<DiffsProps>,
        },
      ],
    };
  },
  // 计算 删除、新增、编辑
  computeTypes(arr: Array<any>, idx: number, id: string) {
    const dCartInfo: Array<DiffsProps> = [];
    const dText = this.getDiffArr(arr[0].value, arr[1].value);

    dText.forEach((dArr, index) => {
      let edit = false;
      // 新增(1 是新增  新增的上一行是-1 则是编辑)
      if (dArr[0] === 1) {
        if (dText[index - 1] && dText[index - 1][0] === -1) {
          edit = true;
          dCartInfo.push({
            name: '修改',
            type: 'edit',
            id: idx,
            key: id,
            last: dText[index - 1][1],
            next: dArr[1],
          });
        }
        if (!edit) {
          dCartInfo.push({
            name: '新增',
            type: 'add',
            id: idx,
            key: id,
            last: '',
            next: dArr[1],
          });
        }
      }

      // 删除(-1 是删除  删除的下一行是1 则是编辑)
      if (dArr[0] === -1) {
        if (dText[index + 1] && dText[index + 1][0] === 1) {
          edit = true;
          dCartInfo.push({
            name: '修改',
            type: 'edit',
            id: idx,
            key: id,
            last: dArr[1],
            next: dText[index + 1][1],
          });
        }
        if (!edit) {
          dCartInfo.push({
            name: '删除',
            type: 'remove',
            id: idx,
            key: id,
            last: '',
            next: dArr[1],
          });
        }
      }
    });

    return dCartInfo;
  },

  getDiffArr(prev: string, current: string) {
    var dmp = new DiffMatchPatch();
    var d = dmp.diff_main(prev as string, current as string);
    return d;
  },
};

export default Compare;
