import React, { useEffect, useState, useMemo } from 'react';
// import { default as AntcodeCR } from 'acr';
import { ACR } from 'alex';
import { Button, Switch, Spin, Icon } from 'antd';
// blame worker扩展
import CodeBlame from './extensions/alex-ext-public.editor-plugin-blame.js';
// 通过在plugin内调用扩展中的命令来进行外部交互
import CodeBlamePlugin, { ExtensionCommand } from './plugins/code-blame.plugin';
import { usePersistFn } from "ahooks";
import {windowsOrMac} from 'educoder';

import {
  Provider,
  useGlobal,
  usePr,
  useNote,
  useReadMark,
  useAcr,
  useSetting,
} from './model';
import {
  DiscussionItem,
  Commenting,
  Menubar,
  AnnotationEntry,
  PRMoreActionLinks,
} from './mock/component/index';
import { projectService } from './mock/project.service';
import { lsifService } from './mock/lsif.service';
import { useFileReadMarkChange$ } from './hooks';
import { repoService } from './mock/repo.service';
import ideLogo from './ideLogo.svg';


const CodeReview = (props) => {
  const { match: { params: { owner, projectsId, mergeId } }, projectDetail, current_user } = props;
  const [visible, setVisible] = React.useState(true);
  const [count, setCount] = React.useState(0);
  const [isFullscreen, setFullscreen] = React.useState(false);
  const { locale, setLocale, gbk, setGBK } = useSetting();
  const { commentPack } = useNote();
  const { project, user, setCurrent_user, setProjectDetail } = useGlobal();
  const { pr } = usePr();


  const {
    getFileReadStatus: _getFileReadStatus,
    markFileAsRead,
    markFileAsUnread,
    readMarks,
  } = useReadMark();
  // todo
  const getFileReadStatus = usePersistFn(_getFileReadStatus);
  // const getFileReadStatus = _getFileReadStatus;
  const {
    diffsPack,
    getDiffById,
    getFileContent,
    IDEMode,
    toggleViewerType,
    annotationPacks,
    setAcrFlag,
  } = useAcr();
  const fileReadMarkChange$ = useFileReadMarkChange$(
    diffsPack && diffsPack.diffs || [],
    readMarks
  );

  // 插件激活
  const [pluginActivated, setPluginActivated] = useState(false);
  const blamePlugin = useMemo(() => {
    return new CodeBlamePlugin(
      () => setPluginActivated(true),
      (commitId) => {
        window.open(
          `/${owner}/${projectsId}/commit/${commitId}`
        )
      },
      // 获取blame数据
      (projectId, commitId, filepath) =>
        repoService.getCodeBlame(projectsId, owner, { sha: commitId, filepath })
    );
  }, []);

  useEffect(()=>{
    // 设置网页标题
    if(pr && projectDetail){
      const { title} = pr;
      const { author, name} = projectDetail;
      document.title = `代码评审-${title}-${author.name}/${name}`;
    }
  }, [pr, projectDetail])

  useEffect(() => {
    if (!pluginActivated) {
      return;
    }
    const projectData = {
      projectId: projectsId,
      prevSha: diffsPack.fromVersion && diffsPack.fromVersion.headCommitSha || diffsPack.toVersion.baseCommitSha,
      nextSha: diffsPack.toVersion.headCommitSha,
    };
    blamePlugin.commands && blamePlugin.commands.executeCommand(
      ExtensionCommand.setProjectData,
      projectData
    );
    // 取消语言服务
    blamePlugin.commands && blamePlugin.commands.executeCommand(
      'alex.setDefaultPreference',
      'acr.lsifEnabled',
      false
    );
  }, [pluginActivated, diffsPack]);

  if (!diffsPack) {
    return <Spin style={{ height: "100vh" }} spinning={true}></Spin>
  }

  function EditorEmpty() {
    const  system=windowsOrMac();
    return <div className='ide-logo'>
      <img className='ide-logo-img' src={ideLogo} />
      <div>
        <div className='ide-logo-text'>IDE代码体验、高效的代码编辑</div>
        {/* <span className='ide-btn'>⇧</span> */}
        <div className='ide-logo-text'>标记文件为已查看 <span className='ide-btn'>{system==='mac'?'⌥':'Alt'}</span> <span className='ide-btn'>C</span> </div>
        <div className='ide-logo-text'>快速打开变更文件 <span className='ide-btn'>^</span> <span className='ide-btn'>{system==='mac'?'⌥':'Alt'}</span> <span className='ide-btn'>P</span></div>
        <div className='ide-logo-text'>切换变更文件 <span className='ide-btn'>{system==='mac'?'⌥':'Alt'}</span> <span className='ide-btn'>↑</span> / <span className='ide-btn'>↓</span></div>
      </div>
    </div>
  }
  // <Icon className='ide-btn-demo' type="arrow-up" /> <Icon  className='ide-btn-demo' type="arrow-down" />
  const propsIDE = {
    // 评审
    noteIdToReplyIdSet: commentPack.noteIdToReplyIdSet,
    // 增加的总行数
    addLineNum: diffsPack.addLineNum,
    // 删除的总行数
    deleteLineNum: diffsPack.delLineNum,
    // 上一个sha
    prevSha:
      diffsPack.fromVersion && diffsPack.fromVersion.headCommitSha || diffsPack.toVersion.baseCommitSha,
    // 下一个 sha
    nextSha: diffsPack.toVersion.headCommitSha,
    toggleViewerType,
    DiscussionItem,
    Commenting,
    getFileContent,
    lineToNoteIdSet: commentPack.lineToNoteIdSet,
    noteIdToNote: commentPack.noteIdToNote,
    noteUpdateFlag: commentPack.updateFlag,
    getDiffById,
    diffs: diffsPack.diffs,
    latestCommitSha: pr.diff.headCommitSha,
    projectId: projectsId,
    projectPath: `${owner}/${projectsId}`,
    pullRequestId: mergeId,
    pr,
    // 获取主语言
    getLanguages: () =>
      projectService
        .getLanguages(projectsId, {
          aggBy: 'file_extension',
          // 按照语言文件个数排序
          orderBy: 'count',
          size: 20,
        })
        .then((res) => res && Object.keys(res)),
    getFileReadStatus,
    fileReadMarkChange$,
    markFileAsRead,
    markFileAsUnread,
    bulkChangeFiles: (actions, header) => {

      let files = [];
      for (const item of actions) {
        files.push({
          action_type: item.actionType,
          content: item.content,
          encoding: item.encoding,
          file_path: item.filePath,
        });
      }
      let data = {
        files: files,
        author_email: current_user.email,
        author_name: current_user.login,
        committer_email: current_user.email,
        committer_name: current_user.login,
        branch: header.branch,
        message: header.commitMessage,
      };

      if (pr && pr.forkProject) {
        projectService.bulkChangeFiles(pr.forkProject.identifier, pr.forkProject.login, data).then(res => {
          if (res) {
            // gitea底层同步commit是异步，延迟查询才能获取修改后的结果
            setTimeout(() => {
              setAcrFlag({});
            }, 1000)
          }
        })
      } else {
        projectService.bulkChangeFiles(projectsId, owner, data).then(res => {
          if (res) {
            // gitea底层同步commit是异步，延迟查询才能获取修改后的结果
            setTimeout(() => {
              setAcrFlag({});
            }, 1000)
          }
        })
      }
    },
    // 菜单栏
    Menubar: () => (
      <Menubar
        initialFullscreen={isFullscreen}
        handleFullscreenChange={setFullscreen}
        toggleViewerType={toggleViewerType}
        logFullScreen={(bool) => console.log('>>>logFullScreen', bool)}
        projectsId={projectsId}
        owner={owner}
        mergeId={mergeId}
      />
    ),
    user,
    lsifService,
    defaultEncoding: project.encoding,
    // 初始化 编码
    encoding: gbk ? 'gbk' : 'utf-8',
    // 设置编码
    setEncoding: (val) => {
      setGBK(val === 'gbk');
    },
    locale,
    annotations: annotationPacks,
    AnnotationEntry,
    PRMoreActionLinks,
    EditorEmpty: EditorEmpty,
    onigWasmUri: 'https://gw.alipayobjects.com/os/lib/vscode-oniguruma/1.6.2/release/onig.wasm',
    // 全屏模式
    isFullscreen,
    appConfig: {
      // 插件 在插件中调用扩展的命令
      plugins: [blamePlugin],
      // 扩展
      extensionMetadata: [CodeBlame],
    },
  };

  const IDEContainerStyle = {
    position: isFullscreen ? 'fixed' : 'static',
    left: 0,
    top: 0,
    width: '100%',
    height: isFullscreen ? '100vh' : 'calc(100vh - 72px)',
    zIndex: 1002,
  };

  return (

    <div style={{ height: '100%', lineHeight: '1.4' }}>
      {IDEMode && (
        <div style={IDEContainerStyle}>
          {visible && <ACR {...propsIDE} key={count} />}
        </div>
      )}
    </div>

  );
};


const CodeReviewP = (props) => {
  return (
    <Provider {...props}><CodeReview {...props} /></Provider>
  )
}
export default CodeReviewP;

