import React, { Component } from 'react';
import { Input, Select, Spin, Alert } from 'antd';
import axios from 'axios';
import MergeForm from './merge_form';
import MergeFooter from './merge_footer';
import { returnbar , turnbar } from 'educoder';
import { Base64 } from 'js-base64';

import '../Order/order.css';
import './merge.css';

/**
 * 根据url获取目标仓库、目标分支、源仓库、源分支
 * 路由规则：owner/projectId/compare/merge...pullowner:pullBranch
 * 可能存在的情况
 * 1、代码库首页跳转，仓库相同，目标分支为默认分支，owner/projectId/compare/pullBranch
 * 2、代码库分支列表，仓库相同，目标分支为默认分支，owner/projectId/compare/pullBranch
 * 3、合并请求列表页（新建、无数据时的提示），仓库相同，源、目标都为默认分支，owner/projectId/compare
 * 4、新建页面，切换分支、切换目标仓库、刷新页面等，存在所有可能情况
 */
 const limit = 15;

function getBranchParams(pathname) {
  const result = {
    // 目标仓库所有者
    mergeOwner: undefined,
    // 目标分支
    mergeBranch: 'master',
    // 源仓库所有者
    pullOwner: undefined,
    // 源分支
    pullBranch: 'master',
    // 仓库名称
    projectId: undefined,
  };
  // 去掉第一个字符/
  const _pathname = pathname.slice(1);
  const [ownerProject, branchUrl] = _pathname.split('/compare');
  const [mergeOwner, projectId] = ownerProject.split('/');
  // 同仓库时
  result.mergeOwner = mergeOwner;
  result.pullOwner = mergeOwner;
  result.projectId = projectId;
  if (branchUrl) {
    // 如果存在具体的分支
    const _branchUrl = branchUrl.slice(1);
    if (_branchUrl.indexOf('...') > -1) {
      // 存在源分支与目标分支
      const [mergeBranch, pullObj] = _branchUrl.split('...');
      result.mergeBranch = mergeBranch;
      if (pullObj.indexOf(':') > -1) {
        // 存在源仓库
        const [pullOwner, pullBranch] = pullObj.split(':');
        result.pullOwner = pullOwner;
        result.pullBranch = pullBranch;
      } else {
        result.pullBranch = pullObj;
      }
    } else {
      result.pullBranch = _branchUrl;
    }
  }
  return result;
}

const Option = Select.Option;

class CreateMerge extends Component {
  constructor(props) {
    super(props);
    const { pullBranch, mergeBranch } = getBranchParams(
      this.props.location.pathname
    );
    this.state = {
      data: undefined,
      pullBranches: undefined,
      mergeBranches: undefined,
      mergeProjects: undefined,
      merge: returnbar(mergeBranch) || 'master',
      pull: returnbar(pullBranch) || 'master',
      id: undefined,
      // isFork: false,
      projects_names: undefined,
      isSpin: true,
      showMessage: false,
      merge_head: false, // 是否向fork后的源项目发起合并请求
      defaultMessage: '必须选择不同的分支',
      project_id: undefined, // 当前项目的id，也即开始发送合并请求的源项目id
      merge_project_user: undefined,
      comparesData: undefined, //提交和文件的内容，保存compare接口返回的数据
      // 比较分支时的加载效果
      isCompareSpin: true,
      // 是否是初次加载，用这个字段来控制提示组件和文件组件的显示、隐藏比直接用isCompareSpin交互友好些
      isFirstLoading: true,
    };
  }

  componentDidMount = () => {
    // 初始化时根据url获取目标仓库、分支，源仓库、分支；
    // 再获取对应的仓库列表、分支列表
    // 再调用比较接口
    const branchParams = getBranchParams(this.props.location.pathname);
    this.getMergeInfo(branchParams,true);
    this.checkBranch(branchParams);
  };

  componentDidUpdate = (preProps) => {
    // url变化触发时（切换源分支、切换目标仓库、切换目标分支；回退）
    const oldPathname = preProps.location.pathname;
    const newPathname = this.props.location.pathname;
    if (oldPathname !== newPathname) {
      const branchParams = getBranchParams(newPathname);
      this.getMergeInfo(branchParams);
      this.checkBranch(branchParams);
    }
  };

  //获取新建合并请求数据
  getMergeInfo = (branchParams,init) => {
    this.setState({ isSpin: true });
    const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
    const url = `/${pullOwner}/${projectId}/pulls/new.json`;
    axios.get(url).then((result) => {
      if (result) {
        if(init){
          //页面初始化时调用selectProjectName，给is_original、fork_project_id、merge_user_login赋值
          const initUser = result.data.projects_names && result.data.projects_names.filter((item)=>item.project_user_login === branchParams.mergeOwner);
          initUser && initUser[0] && this.selectProjectName(initUser[0].id,false,{projects_names: result.data.projects_names,id: result.data.id});
        }
        this.setState({
          // isFork: result.data.is_fork,
          projects_names: result.data.projects_names,
          mergeProjects: result.data.merge_projects,
          // pullBranches: result.data.branches,
          // mergeBranches: result.data.branches,
          project_id: result.data.project_id,
          id: result.data.id,
          merge: returnbar(mergeBranch),
          pull: returnbar(pullBranch),
        });
        // this.setState({
        //   isSpin: false,isCompareSpin: false
        // });
      }
    })
    .catch((error) => {
      this.setState({ isSpin: false });
      console.log(error);
    });
  };

  checkBranch=async(branchParams)=>{
    const { mergeBranch , mergeOwner, projectId , pullBranch ,pullOwner} = branchParams;
    let getbranch =await this.getBranchList(mergeOwner,projectId,returnbar(pullBranch),returnbar(mergeBranch),"merge");
    let checkpull =await this.getBranchList(pullOwner,projectId,returnbar(pullBranch),returnbar(mergeBranch),"pull");
    if(getbranch && checkpull){
      this.compareProject(mergeOwner === pullOwner, branchParams,1);
    }else{
      this.setState({
        isSpin: false,isCompareSpin: false
      });
    }
  }

  // compare接口，获取分支对比信息
  compareProject = (sameProject, branchParams ,page) => {
    const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
    let url = `/${mergeOwner}/${projectId}/compare`;
    if (sameProject) {
      url += `/${Base64.encode(returnbar(pullBranch))}...${Base64.encode(returnbar(mergeBranch))}.json`;
    } else {
      url += `/${Base64.encode(returnbar(mergeBranch))}...${pullOwner}/${projectId}:${Base64.encode(returnbar(pullBranch))}.json`;
    }
    axios
      .get(url,{
        params:{limit,page}
      })
      .then((result) => {
        if (result) {
          if (result.data.status === 0) {
            this.setState({
              showMessage: false,
            });
          } else {
            this.setState({
              showMessage: true,
              defaultMessage: result.data.message,
            });
          }
          this.setState({
            comparesData: result.data,
            isSpin: false,isCompareSpin: false,isFirstLoading:false
          });
        }
      })
      .catch((error) => {
        this.setState({ isSpin: false, isCompareSpin: false });
      });
  };

  // 根据所有者、仓库名，获取分支列表，目前仅涉及目标仓库分支查询
  getBranchList =async(owner,identifier,branch,mergebranch,type) => {
    const url = `/${owner}/${identifier}/branches.json`;
    let check = await axios.get(url).then((result) => {
      if(result.data){
        let pfilter = (result.data || []).filter(i => i.name === branch).length === 0;
        let mfilter = (result.data || []).filter(i => i.name === mergebranch).length === 0;
        if(type === "pull"){
          this.setState({
            pullBranches:result.data,
          })
        }else{
          this.setState({
            mergeBranches:result.data
          })
        }
        if(type === "pull" && pfilter){
          this.setState({
            showMessage: branch,
            defaultMessage: `源分支不存在`,
            isCompareSpin: false
          });
          return false;
        }
        if(type === "merge" && mfilter){
          this.setState({
            showMessage: mergebranch,
            defaultMessage: `目标分支不存在`,
            isCompareSpin: false
          });
          return false;
        }
        return true;
      }
    })
    .catch((error) => {
      this.setState({ isSpin: false });
      check = false;
    });
    return check;
  };

  // 切换分支事件
  selectBrach = (type, value) => {
    const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } =
      getBranchParams(this.props.location.pathname);
    let _url = `/${mergeOwner}/${projectId}/compare/`;
    // type为pull时，pullBranch取value，否则取原有值
    // type为pull时，mergeBranch取原有值，否则取value
    let _pullBranch = type === 'pull' ? value : pullBranch;
    let _mergeBranch = type === 'pull' ? mergeBranch : value;
    if (pullOwner === mergeOwner) {
      // 如果仓库相同, compare/目标分支...源分支
      _url += `${turnbar(_mergeBranch)}...${turnbar(_pullBranch)}`;
    } else {
      // 如果仓库不同, compare/目标分支...源分支
      _url += `${turnbar(_mergeBranch)}...${pullOwner}:${turnbar(_pullBranch)}`;
    }
    this.props.history.push(_url);
  };

  // 切换仓库响应事件，目前仅目标分支可切换仓库
  selectProjectName = (value, isChangeProject, initPro) => {
    const { projects_names, id } = isChangeProject ? this.state : initPro;
    const { pullOwner, pullBranch } = getBranchParams(
      this.props.location.pathname
    );
    let arr =
      projects_names && projects_names.filter((item) => item.id === value);
    let identifier = arr && arr[0].project_id;
    let login = arr && arr[0].project_user_login;
    // 目标仓库与源仓库不是一个仓库
    let is_fork = parseInt(value, 10) !== parseInt(id, 10);
    this.setState({
      // 切换目标仓库时url会发生变化，即有spin效果
      // isSpin: true,
      // merge_head: is_fork,
      data: {
        is_original: is_fork,
        fork_project_id: is_fork ? id : '',
        merge_user_login: is_fork
          ? projects_names[0].project_user_login
          : undefined,
      },
    });
    // 加上是否需要切换url判断
    if(isChangeProject){
      const { defaultBranch } = this.props;
      let branch = turnbar(defaultBranch) || "master";
      if (login === pullOwner) {
        // 如果切换后, 仓库与源仓库一致了
        this.props.history.push(
          `/${login}/${identifier}/compare/${branch}...${turnbar(pullBranch)}`
        );
      } else {
        this.props.history.push(
          `/${login}/${identifier}/compare/${branch}...${pullOwner}:${turnbar(pullBranch)}`
        );
      }
    }
    // this.newMergelist(login, identifier);
  };

  // 渲染分支列表
  renderBrances = (list) => {
    if (list && list.length > 0) {
      return list.map((item, key) => {
        return (
          <Option key={key + 1} value={item.name}>
            {item.name}
          </Option>
        );
      });
    }
  };

  // 渲染项目列表
  renderProjectNames = (list) => {
    if (list && list.length > 0) {
      return list.map((item, key) => {
        return (
          <Option key={key + 1} value={item.id}>
            {item.project_name}
          </Option>
        );
      });
    }
  };

  // 渲染html内容
  withHtml = (html) => {
    return <div dangerouslySetInnerHTML={{ __html: html }}></div>;
  };

  // 源分支-分支搜索
  changePullValue=async(value,cate)=>{
    const branchParams = getBranchParams(this.props.location.pathname);
    const { pullOwner, mergeOwner , projectId } = branchParams;
    const url = `/${cate === "pull" ? pullOwner :mergeOwner}/${projectId}/pulls/get_branches.json`;
    axios.get(url,{
      params:{
        name:value || undefined,
      }
    }).then(result=>{
      if(result){
        if(cate === "pull"){
          this.setState({
            pullBranches:result.data,
            pullBranch:result.data
          })
        }else{
          this.setState({
            mergeBranches:result.data,
            mergeBranch:result.data
          })
        }
      }
    }).catch(error=>{})
  }

  changeCommitFunc=(page)=>{
    this.setState({
      isSpin:true
    })
    const branchParams = getBranchParams(this.props.location.pathname);
    const { mergeOwner , pullOwner} = branchParams;
    this.compareProject(mergeOwner === pullOwner, branchParams,page);
  }

  render() {
    const {
      data,
      pullBranches,
      mergeBranches,
      mergeProjects,
      pull,
      merge,
      isSpin,
      isCompareSpin,
      isFirstLoading,
      showMessage,
      defaultMessage,
      projects_names,
      id,
      comparesData,
    } = this.state;

    let { project } = this.props;
    return (
      <div>
        <Spin spinning={isSpin || isCompareSpin}>
          <div className="main">
            <div className="merge-header width100 inline-block">
              <div className="width40 pull-left">
                <div className="color-grey-3 mb10 fwb">源分支 : </div>
                <Input.Group compact className="display-flex">
                  <Select
                    value={id}
                    className="hide-1 task-hide flex1"
                    disabled
                  >
                    {this.renderProjectNames(projects_names)}
                  </Select>
                  <Select
                    value={pull}
                    onSelect={(e) => this.selectBrach('pull', e)}
                    showSearch
                    className="merge-flex1 flex1 matchwidth"
                    dropdownMatchSelectWidth={false}
                    dropdownClassName="overlihide"
                    // onSearch={(e)=>this.changePullValue(e,"pull")}
                    // filterOption={(input,option)=>option}
                  >
                    {this.renderBrances(pullBranches)}
                  </Select>
                </Input.Group>
              </div>
              <div className="width10 pull-left text-center mt25">
                <i
                  className={'iconfont icon-youjiang color-grey-c font-32'}
                ></i>
              </div>
              <div className="width40 pull-left">
                <div>
                  <div className="color-grey-3 mb10 fwb">目标分支 : </div>
                  <Input.Group compact className="display-flex">
                    <Select
                      value={project && project.id}
                      className="hide-1 task-hide flex1"
                      onSelect={(e) => this.selectProjectName(e, true)}
                    >
                      {this.renderProjectNames(mergeProjects)}
                    </Select>
                    <Select
                      value={merge}
                      onSelect={(e) => this.selectBrach('merge', e)}
                      showSearch
                      className="merge-flex1 flex1 matchwidth"
                      dropdownMatchSelectWidth={false}
                      dropdownClassName="overlihide"
                      // onSearch={(e)=>this.changePullValue(e,"merge")}
                      // filterOption={(input,option)=>option}
                    >
                      {this.renderBrances(mergeBranches)}
                    </Select>
                  </Input.Group>
                </div>
              </div>
            </div>
            {/* 非加载状态且有提示 */}
            {!isCompareSpin && showMessage && (
              <div className="mb20">
                <Alert
                  description={this.withHtml(defaultMessage)}
                  type="error"
                />
              </div>
            )}
            {/* 非加载状态且可以提交 */}
            {!isCompareSpin && !showMessage && (
              <MergeForm
                {...this.props}
                merge_type="new"
                data={data}
                merge={merge}
                pull={pull}
                files_count={
                  comparesData &&
                  comparesData.diff &&
                  comparesData.diff.files_count
                }
                commits_count={comparesData && comparesData.commits_count}
              ></MergeForm>
            )}
          </div>
          {!isFirstLoading && (
            <MergeFooter
              {...this.props}
              merge={merge}
              pull={pull}
              limit = {limit}
              changeCommitFunc={this.changeCommitFunc}
              comparesData={comparesData}
            ></MergeFooter>
          )}
        </Spin>
      </div>
    );
  }
}

export default CreateMerge;
