/*
 * @Descripttion: 安徽马鞍山导入接口
 * @Author: vian
 * @Date: 2020-09-09 11:51:15
 */

// INTERFACE_EXPORT =，必须这么写，这样才能在导入时动态加载脚本后，覆盖前端代码
INTERFACE_IMPORT = (() => {
  'use strict';
  /**
   * 
   * @param {String} areaKey - 地区标识，如：'安徽@马鞍山'，有些地区的接口只是取值上有不同，共有一个接口脚本， 需要通过地区标识确定一些特殊处理
   * @param {Object} xmlObj - xml经过x2js转换后的xml对象
   * @return {Object} - 返回的格式需要统一，具体参考函数内返回的内容。返回的内容会经过一系列的统一处理形成可入库的数据。
   */
  async function entry(areaKey, xmlObj) {
    const {
      UTIL: {
        getValue,
        arrayValue,
        getBool,
        extractItemsRecur,
      }
    } = INTERFACE_EXPORT_BASE;

    const subArea = areaKey.split('@')[1];

    const taxModeMap = {
      '1': '一般计税',
      '2': '简易计税',
    };
    // 提取基本信息，xml中提取出来的基本信息，最终会与模板基本信息进行合并处理。（接口内不需要处理合并）
    function setupInformation(projectSrc) {
      // key：基本信息模板中的key，作为合并时的匹配字段
      const info = [
        { key: 'projNum', value: getValue(projectSrc, ['_Xmbh']) },
        { key: 'projType', value: getValue(projectSrc, ['_Bzlx']) },
        { key: 'startEndChainages', value: getValue(projectSrc, ['_Xmqzzh']) },
        { key: 'constructingUnits', value: getValue(projectSrc, ['_Jsdw']) },
        { key: 'taxMode', value: taxModeMap[getValue(projectSrc, ['_Jsfs'])] || '' },
        { key: 'tendereeName', value: getValue(projectSrc, ['ZhaoBiaoXx', '_Zbr']) },
        { key: 'costConsultant', value: getValue(projectSrc, ['ZhaoBiaoXx', '_Zxr']) },
        { key: 'tenderAuthorizer', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZbrDb']) },
        { key: 'consultantAuthorizer', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZxrDb']) },
        { key: 'tenderCompiler', value: getValue(projectSrc, ['ZhaoBiaoXx', '_Bzr']) },
        { key: 'tenderExaminer', value: getValue(projectSrc, ['ZhaoBiaoXx', '_Fhr']) },
        { key: 'compilationTime', value: getValue(projectSrc, ['ZhaoBiaoXx', '_BzTime']) },
        { key: 'reviewTime', value: getValue(projectSrc, ['ZhaoBiaoXx', '_FhTime']) },
      ];
      // 工程所在地，以第一个单位工程为准，在费率项中
      const firstEng = arrayValue(projectSrc, ['Dxgcxx'])[0];
      const firstTender = firstEng ? arrayValue(firstEng, ['Dwgcxx'])[0] : null;
      if (firstTender) {
        const feeRateItems = arrayValue(firstTender, ['Qfxx', 'JjFlx', 'JjFlxMx']);
        const locationItem = feeRateItems.find(item => getValue(item, ['_Mc']) === '工程所在地');
        if (locationItem) {
          info.push({ key: 'location', value: getValue(locationItem, ['_ShuZhi']) });
        }
      }
      if (['淮北', '铜陵', '六安'].includes(subArea)) {
        const extraInfo = [
          { key: 'tendereeTaxpayerIdentificationNo', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZbrNssbh']) },
          { key: 'costConsultantTaxpayerIdentificationNo', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZxrNssbh']) },
          { key: 'tenderAuthorizerIDNo', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZbrDbSfzh']) },
          { key: 'consultantAuthorizerTaxpayerIdentificationNo', value: getValue(projectSrc, ['ZhaoBiaoXx', '_ZxrDbSfzh']) },
        ];
        info.push(...extraInfo);
      }
      return info;
    }

    // 提取工程特征信息，xml中提取出来的工程特征，最终会与模板工程特征进行合并处理。（接口内不需要处理合并）
    function setupFeature(midSrc, tenderSrc) {
      return [
        { key: 'singleProjNo', value: getValue(midSrc, ['_Dxgcbh']) }, // 单项工程编号
        { key: 'singleProjName', value: getValue(midSrc, ['_Dxgcmc']) }, // 单项工程名称
        { key: 'unitProjNo', value: getValue(tenderSrc, ['_Dwgcbh']) },
      ];
    }

    // 费率值映射表，“接口中可有效识别的费率值类型值，此接口是Bm”与“软件中对应费率标准的名称”映射。
    const feeRateValueMap = {
      'DJF': '冬季施工增加费',
      'YJF': '雨季施工增加费',
      'YEF': '夜间施工增加费',
      'GYF': '高原地区施工增加费',
      'FSF': '风沙地区施工增加费',
      'YHF': '沿海地区施工增加费',
      'XCF': '行车干扰施工增加费',
      'ZYF': '工地转移费',
      'SFF': '施工辅助费',
      'JBF': '基本费用',
      'YFF': '主副食运费补贴',
      'TQF': '职工探亲路费',
      'QNF': '职工取暖补贴',
      'CWF': '财务费用',
      'YLF': '养老保险费',
      'SYF': '失业保险费',
      'YBF': '医疗保险费',
      'GSF': '工伤保险费',
      'ZFF': '住房公积金',
      'LR': '利润',
      'SJ': '税金',
    };

    // 费率工程类型映射表， “接口中可有效识别的工程类型值，此接口是Qflb”与“袁建中对应费率标准的工程类型名称”映射
    const feeRateParentTypeMap = {
      1: '土方',
      2: '运输',
      3: '石方',
      4: '路面',
      4: '路面(不计雨)',
      5: '构造物Ⅰ',
      6: '构造物Ⅱ',
      8: '构造物Ⅲ(除桥以外)',
      8: '构造物Ⅲ(除桥以外不计雨夜)',
      9: '构造物Ⅲ(桥梁)',
      10: '技术复杂大桥',
      11: '隧道',
      12: '钢材及钢结构(桥梁)',
      13: '钢材及钢结构(除桥以外)',
      13: '钢材及钢结构(除桥以外不计夜)',
      14: '量价',
      15: '设备',
      16: '构造物Ⅰ(不计冬)',
      16: '构造物Ⅰ(不计雨)',
      17: '费率为0',
    };

    const feeRateParamMap = {
      djsg: '冬季施工',
      yjsg: '雨季施工',
      yjsg: '夜间施工',
      gysg: '高原施工',
      fssg: '风沙施工',
      yhsg: '沿海施工',
      hcgr: '行车干扰',
      gdzy: '工地转移(km)',
      sgfz: '施工辅助',
      jbfy: '基本费用',
      zhlc: '综合里程(km)',
      zgtq: '职工探亲',
      zgqn: '职工取暖',
      cwfy: '财务费用',
      ylbx: '养老保险(％)',
      sybx: '失业保险(％)',
      ylbx: '医疗保险(％)',
      gsbx: '工伤保险(％)',
      zfgj: '住房公积金(％)',
      lr: '利润(%)',
      sj: '税金(%)',
    };

    // 提取费率数据(费率值、费率参数)，最终会与标准费率数据进行合并。（接口内不需要处理合并）
    function setupFeeRate(feeRateSrc) {
      // 提取费率值数据
      const valueItems = arrayValue(feeRateSrc, ['JjFlb', 'JjFlbMx'])
        .map(item => ({
          parentType: feeRateParentTypeMap[getValue(item, ['_Qflb'])] || '',
          type: feeRateValueMap[getValue(item, ['_Bm'])] || '',
          value: getValue(item, ['_Fl'])
        }));
      // 提取费率参数数据
      const paramItems = arrayValue(feeRateSrc, ['JjFlx', '_JjFlxMx'])
        .map(item => ({
          type: feeRateParamMap[getValue(item, ['_Bm'])] || '',
          value: getValue(item, ['_ShuZhi'])
        }));
      return { valueItems, paramItems };
    }

    // 提取清单数据
    function setupBills(billsSrc) {
      const qdbt = 'QdBt';
      const qdmx = 'QdMx';
      const jrg = 'Jrg';
      const jrgbt = 'JrgBt';
      const fields = [[qdbt], [qdmx], [jrg, jrgbt]];
      return extractItemsRecur(billsSrc, fields, (src, curField) => {
        let item = {
          name: getValue(src, ['_Name']),
          remark: getValue(src, ['_Bz']),
        }
        if (curField === qdbt) {
          item.code = getValue(src, ['_Bm']);
          item.rowCode = getValue(src, ['_Code']); // 注意：行号标记，用于后续（通用处理）清单基数进行转换（行引用转换为ID引用） 
          const titleType = getValue(src, ['_Lb']);
          item.titleType = titleType;
          /* if (titleType === '5') { // 暂列金额才导入计算基数
            item.tempCalcBase = getValue(src, ['_Jsgs']);
          } */
          item.tempCalcBase = getValue(src, ['_Jsgs']);
        } else if (curField === qdmx) {
          item.code = getValue(src, ['_Qdbm']);
          item.unit = getValue(src, ['_Dw']);
          item.quantity = getValue(src, ['_Sl']);
          item.unitPriceAnalysis = +getBool(src, ['_Djfx']); // 单价分析
          item.specialProvisional = getBool(src, ['_Iszg']) ? '专业工程' : ''; // 是否暂定
          if (item.specialProvisional) {
            item.tempCalcBase = getValue(src, ['_Jsgs']);
          }
        }
        return item;
      });
    }

    // 提取人材机数据（暂估材料和评标材料）
    function setupGLJSummary(tenderSrc) {
      function gljRefMapFunc(glj) {
        return {
          seq: getValue(glj, ['_Xh']),
          code: getValue(glj, ['_Bm']),
          name: getValue(glj, ['_Mc']),
          specs: getValue(glj, ['_Ggxh']),
          unit: getValue(glj, ['_Dw']),
          quantity: getValue(glj, ['_Sl']),
          marketPrice: getValue(glj, ['_Dj']),
          totalPrice: getValue(glj, ['_Hj']),
          remark: getValue(glj, ['_Bz']),
        };
      }
      return {
        evaluationList: arrayValue(tenderSrc, ['ZgCl', 'ZgClMx']).map(gljRefMapFunc),
        bidEvaluationList: arrayValue(tenderSrc, ['JpCl', 'JpClMx']).map(gljRefMapFunc),
      };
    }

    // 提取单位工程数据
    function setupTender(midSrc, tenderSrc) {
      //const feeRateSrc = getValue(tenderSrc, ['Qfxx']);
      const billsSrc = getValue(tenderSrc, ['QdXm']);
      return {
        name: getValue(tenderSrc, ['_Dwgcmc']),
        feature: setupFeature(midSrc, tenderSrc),
        //feeRate: setupFeeRate(feeRateSrc),
        bills: setupBills(billsSrc),
        ...setupGLJSummary(tenderSrc),
      };
    }

    // 从xml对象提取需要的数据
    function setupProject(projectSrc) {
      const tenders = [];
      arrayValue(projectSrc, ['Dxgcxx'])
        .forEach(midSrc => {
          arrayValue(midSrc, ['Dwgcxx'])
            .forEach(tenderSrc => tenders.push(setupTender(midSrc, tenderSrc)))
        });
      return {
        name: getValue(projectSrc, ['_Xmmc']),
        info: setupInformation(projectSrc),
        tenders,
      };
    }


    return setupProject(getValue(xmlObj, ['JingJiBiao']));
  }

  return {
    entry
  };

})();