package com.huigou.topsun.syncOrg.application.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.topsun.common.OrgKindId;
import com.huigou.topsun.sap.common.DefaultHttpClient;
import com.huigou.topsun.sap.common.application.SapMutualEpLogApplication;
import com.huigou.topsun.sap.common.domain.SapResult;
import com.huigou.topsun.syncOrg.application.OrgSyncApplication;
import com.huigou.topsun.syncOrg.vo.*;
import com.huigou.topsun.syncOrg.vo.SapPersonVo.BankVo;
import com.huigou.topsun.syncOrg.vo.SapPersonVo.CompanyCodeVo;
import com.huigou.topsun.syncOrg.vo.SapPersonVo.MdClientSapVo;
import com.huigou.topsun.syncOrg.vo.SapPersonVo.SapPersonVo;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.uasp.bmp.opm.domain.model.org.Org;
import com.huigou.uasp.bmp.opm.domain.model.org.Person;
import com.huigou.uasp.bmp.opm.repository.org.OrgRepository;
import com.huigou.uasp.bmp.opm.repository.org.PersonRepository;
import com.huigou.util.DateUtil;
import com.huigou.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: xin.lu
 * @Date: 2024/03/25/9:28
 * @Description:
 */
@Service("orgSyncApplication")
public class OrgSyncApplicationImpl extends BaseApplication implements OrgSyncApplication {
    private final static Logger LOG = LoggerFactory.getLogger(OrgSyncApplicationImpl.class);
    @Autowired
    private OrgRepository orgRepository;
    @Autowired
    private DefaultHttpClient httpClient;
    @Autowired
    SapMutualEpLogApplication sapMutualEpLogApplication;
    @Autowired
    private PersonRepository personRepository;

    @Override
    public EpOrgVo buildOrgVo () {
        List<Org> orgList = orgRepository.findAll();
        orgList = orgList
                .stream()
                .filter(org -> !"INIT_ORG".equals(org.getOrgCode()))
                .collect(Collectors.toList());
        //机构、部门、岗位
        List<OrgVo> orgVoList = orgList
                .stream()
                .filter(org -> !OrgKindId.PSM.getId().equals(org.getOrgKindId()))
                .map(org -> {
                    OrgVo orgVo = new OrgVo();
                    BeanUtil.copyProperties(org,orgVo);
                    orgVo.setDelFlag("0");
                    //把id做hash处理，得到int类型数据
                    orgVo.setId(convertHashCode(org.getId()));

                    //从全路径中获取当前组织的父节点名称
                    if (StringUtil.isNotBlank(org.getParentId())){
                        String fullName = org.getFullName();
                        String[] split = fullName.split("/");
                        orgVo.setParentName(split[split.length - 2]);

                        //把父id做hash处理，得到int类型数据
                        orgVo.setParentId(convertHashCode(org.getParentId()));
                    }
                    return orgVo;
                })
                .collect(Collectors.toList());

        //人员
        List<Org> psmList = orgList
                .stream()
                .filter(org -> OrgKindId.PSM.getId().equals(org.getOrgKindId()))
                .collect(Collectors.toList());

        //先同步机构、部门、岗位、再同步组织人员
        List<OrgPersonVo> orgPersonVoList = this.buildOrgPersonVo(psmList);

        //同步人员
        List<PersonVo> personVoList = this.buildPersonVo(psmList);

        EpOrgVo epOrgVo = new EpOrgVo();
        epOrgVo.setOrgVoList(orgVoList);
        epOrgVo.setOrgPersonVoList(orgPersonVoList);
        epOrgVo.setPersonVoList(personVoList);
        //LOG.info(DateUtil.getDateFormat(new Date())+"====同步的组织结构数据===={}",epOrgVo);
        return epOrgVo;
    }

    @Override
    public List<OrgPersonVo> buildOrgPersonVo(List<Org> psmList){
        return psmList
                .stream()
                .map(orgPerson -> {
                    OrgPersonVo orgPersonVo = new OrgPersonVo();
                    //组织人员id
                    orgPersonVo.setId(convertHashCode(orgPerson.getId()));
                    //部门id
                    orgPersonVo.setDeptId(convertHashCode(orgPerson.getDeptId()));
                    //岗位id
                    orgPersonVo.setPositionId(convertHashCode(orgPerson.getPositionId()));
                    //人员id
                    orgPersonVo.setPersonId(convertHashCode(orgPerson.getPerson().getId()));
                    return orgPersonVo;
                }).collect(Collectors.toList());
    }

    @Override
    public List<PersonVo> buildPersonVo(List<Org> psmList){
        return psmList
                .stream()
                .map(psm -> {
                    Person person = psm.getPerson();
                    PersonVo personVo = new PersonVo();
                    BeanUtil.copyProperties(person, personVo);
                    personVo.setDelFlag("0");
                    //把人员id做hash处理，得到int类型数据
                    personVo.setId(convertHashCode(person.getId()));
                    personVo.setDeptId(convertHashCode(psm.getDeptId()));
                    return personVo;
                }).collect(Collectors.toList());
    }

    @Override
    public void syncPersonListToSap() {
        List<SapPersonVo> sapPersonVos = this.slicedSapPersonVoList();
        this.buildSapPerson("",sapPersonVos);
    }

    @Override
    public void syncPersonToSap(String flag, List<String> codes) {
        List<SapPersonVo> sapPersonVos = this.slicedSapPersonVo(codes);
        this.buildSapPerson(flag,sapPersonVos);
    }

    @Override
    public void buildSapPerson(String flag,List<SapPersonVo> sapPersonVoList) {
        List<MdClientSapVo> mdClientSapVoList = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        for (SapPersonVo sapPersonVo : sapPersonVoList) {
            MdClientSapVo mdClientSapVo = new MdClientSapVo();
            mdClientSapVo.setUpdkz(StringUtil.isNotBlank(flag)?flag:sapPersonVo.getFlag());//第一次新增I,修改U,删除D
            mdClientSapVo.setRltyp("FLCU00");//BP角色，财务客户
            mdClientSapVo.setBuGroup("C007");//业务伙伴分类，员工客户
            mdClientSapVo.setKunnr(sapPersonVo.getCode());//员工编码
            mdClientSapVo.setNameOrg1(sapPersonVo.getName());//名称
            mdClientSapVo.setNameOrg3(sapPersonVo.getEnglishName());//英文名称
//            if (StringUtil.isBlank(sapPersonVo.getEnglishName())){
//                mdClientSapVo.setNameOrg3(sapPersonVo.getName());//
//            }
            mdClientSapVo.setBuSort1(sapPersonVo.getName());//搜索词
            mdClientSapVo.setSmtpAddr(sapPersonVo.getEmail());//邮件
            if ("0".equals(sapPersonVo.getSex())){
                mdClientSapVo.setTitle("0002");//男
            }else if ("1".equals(sapPersonVo.getSex())){
                mdClientSapVo.setTitle("0001");//女
            }
            mdClientSapVo.setTelNumber(sapPersonVo.getOfficePhone());//办公电话
            mdClientSapVo.setMobNumber(sapPersonVo.getMobilePhone());//移动电话
            mdClientSapVo.setPostCode1(sapPersonVo.getZip());//邮编
            mdClientSapVo.setStras(sapPersonVo.getFamilyAddress());//家庭住址
            mdClientSapVo.setLand1(sapPersonVo.getCountry());//国家
            mdClientSapVo.setLangu(sapPersonVo.getLangu());//语言
            mdClientSapVo.setRegion(sapPersonVo.getRegion());//地区
            mdClientSapVo.setKonzs(sapPersonVo.getKostl());//成本中心
            //银行信息
            List<BankVo> bankVoList = new ArrayList<>();
            BankVo bankVo = new BankVo();
            bankVo.setBanks(sapPersonVo.getBankCountry());//银行所属国家
            bankVo.setBankl(sapPersonVo.getBankCode());//银行代码
            //银行账户
            if (sapPersonVo.getBankAccountNumber().length() > 18){
                String bankn = sapPersonVo.getBankAccountNumber();
                bankVo.setBankn(bankn.substring(0,18));
                //bankVo.setBankn(bankn);
                //账户明细放18位后的值
                bankVo.setBkref(bankn.substring(18,bankn.length()));
            }else {
                bankVo.setBankn(sapPersonVo.getBankAccountNumber());
            }
            bankVo.setKoinh(sapPersonVo.getName());//账户持有人姓名
            bankVo.setAccname(sapPersonVo.getName());//银行账户的名称
            bankVoList.add(bankVo);

            //公司信息
            List<CompanyCodeVo> companyCodeVoList = new ArrayList<>();
            CompanyCodeVo companyCodeVo = new CompanyCodeVo();
            companyCodeVo.setBukrs(sapPersonVo.getCompanyCode());//公司代码
            companyCodeVo.setAkont("1221050000");//其他应收款-个人往来款
            companyCodeVo.setZuawa("001");//排序
            companyCodeVoList.add(companyCodeVo);

            mdClientSapVo.setBank(bankVoList);
            mdClientSapVo.setKnb1(companyCodeVoList);
            mdClientSapVoList.add(mdClientSapVo);

            ids.add(sapPersonVo.getId());
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("businessType", "人员部门主数据");
        resultMap.put("businessId", DateUtil.getDateFormat(new Date(),"yyyy-MM-dd HH:mm:ss"));
        resultMap.put("parameter", JSON.toJSONString(mdClientSapVoList));
        resultMap.put("sequence", resultMap.get("row"));
        try {
            String result = httpClient.execute(mdClientSapVoList, "cud_custom/customer");
            List<SapResult> sapResultList = JSONObject.parseArray(result, SapResult.class);
            if (sapResultList.size()<1){
                throw new RuntimeException("数据传输失败，没有收到返回结果：" + sapResultList);
            }
            List<Person> personList = personRepository.findAll(ids);
            if (!CollectionUtils.isEmpty(sapPersonVoList) && !CollectionUtils.isEmpty(personList)){
                for (Person person : personList) {
                    for (SapResult sapResult : sapResultList) {
                        if ("E".equals(sapResult.getTYPE())){
                            person.setType(sapResult.getTYPE());
                            person.setMessage(sapResult.getMESSAGE());
                        }else {
                            //根据返回的编码匹配是否传成功
                            if (sapResult.getMESSAGE().contains(person.getCode()) || sapResult.getMESSAGE_V1().contains(person.getCode())){
                                person.setType(sapResult.getTYPE());
                                person.setMessage(sapResult.getMESSAGE());
                            }
                        }
                    }
                }
            }
            personRepository.save(personList);
            resultMap.put("TYPE", "S");
            resultMap.put("message", "成功");
        } catch (Exception e) {
            resultMap.put("TYPE", "E");
            resultMap.put("message", e.getMessage());
            throw new RuntimeException("数据传输失败请检查数据后重试！" + e.getMessage());
        } finally {
            //sapMutualEpLogApplication.saveSapMutualEpLog(resultMap);
        }
    }

    @Override
    public List<SapPersonVo> slicedSapPersonVoList() {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedSapPersonVoList");
        return this.sqlExecutorDao.queryToList(queryDescriptor.getSql(), SapPersonVo.class);
    }

    @Override
    public List<SapPersonVo> slicedSapPersonVo(List<String> codes) {
        String code = String.join(",", codes);
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedSapPersonVo");
        return this.sqlExecutorDao.queryToList(queryDescriptor.getSql(), SapPersonVo.class,code);
    }

    @Override
    public List<Person> queryPersonCodeByFullId(String fullId) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryCodeByFullId");
        return this.sqlExecutorDao.queryToList(queryDescriptor.getSql(),Person.class, fullId);
    }

    @Override
    public List<SapPersonVo> querySapPersonVoByFullId(String fullId) {
        StringBuilder stringBuffer = new StringBuilder();
        StringBuilder append = stringBuffer.append("%").append(fullId).append("%");
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "querySapPersonVoByFullId");
        return this.sqlExecutorDao.queryToList(queryDescriptor.getSql(),SapPersonVo.class, append.toString());
    }

    @Override
    public void syncAllPersonToSap() {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedAllSapPersonVo");
        List<SapPersonVo> sapPersonVos = this.sqlExecutorDao.queryToList(queryDescriptor.getSql(), SapPersonVo.class);
        this.buildSapPerson("I",sapPersonVos);
    }

    @Override
    public List<String> getCodeById(List<String> personIds) {
        List<Person> personList = personRepository.findAll(personIds);
        List<String> list = personList
                .stream()
                .filter(person -> "1".equals(person.getIsSapPerson()))
                .map(Person::getCode)
                .collect(Collectors.toList());
        return list;
    }

    /**
     * 字符串转hashcode
     * @param value
     * @return
     */
    public String convertHashCode(String value){
        if (StringUtil.isBlank(value)){
            return "";
        }
        int abs = Math.abs(value.hashCode());
        return String.valueOf(abs);
    }
}
