package com.dxhy.manage.service.impl;

import java.util.*;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxhy.certificate.model.ReturnTokenModel;
import com.dxhy.certificate.service.AuthTokenService;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.utils.Aops;
import com.dxhy.common.utils.PageUtils;
import com.dxhy.common.utils.Query;
import com.dxhy.common.utils.annotation.DataFilter;
import com.dxhy.manage.config.ManageConstants;
import com.dxhy.manage.dao.SysDeptDao;
import com.dxhy.manage.entity.SysDeptEntity;
import com.dxhy.manage.model.FunctionModel;
import com.dxhy.manage.model.ReturnModel;
import com.dxhy.manage.model.VersionModel;
import com.dxhy.manage.service.SysDeptService;
import com.dxhy.manage.service.TaxManageService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@SuppressWarnings("AlibabaUndefineMagicConstant")
@Service("sysDeptService")
@Slf4j
public class SysDeptServiceImpl extends ServiceImpl<SysDeptDao, SysDeptEntity> implements SysDeptService {
    @Resource
    private TaxManageService taxManageService;
    @Resource
    private AuthTokenService authTokenService;

    @Override
    public List<SysDeptEntity> queryList(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return this.getChildPerms(baseMapper.queryList(company), 0);
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list
     *            分类表
     * @param parentId
     *            传入的父节点ID
     * @return String
     */
    public List<SysDeptEntity> getChildPerms(List<SysDeptEntity> list, long parentId) {
        List<SysDeptEntity> returnList = new ArrayList<>();
        for (SysDeptEntity t : list) {
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     *            菜单列
     * @param t
     *            菜单信息
     */
    private void recursionFn(List<SysDeptEntity> list, SysDeptEntity t) {
        // 得到子节点列表
        List<SysDeptEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDeptEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysDeptEntity n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDeptEntity> list, SysDeptEntity t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 得到子节点列表
     */
    private List<SysDeptEntity> getChildList(List<SysDeptEntity> list, SysDeptEntity t) {
        List<SysDeptEntity> tlist = new ArrayList<>();
        for (SysDeptEntity n : list) {
            if (Objects.equals(n.getParentId(), t.getDeptId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    @Override
    public List<SysDeptEntity> queryListUser(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryListUser(company);
    }

    @Override
    @DataFilter(subDept = true, user = false, tableAlias = "t1")
    public List<SysDeptEntity> queryListParent(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryListParent(company);
    }

    @Override
    public List<Long> queryDetpIdList(Long parentId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryDetpIdList(parentId);
    }

    @Override
    public List<Long> getSubDeptIdList(Long deptId) {
        // 部门及子部门ID列表
        List<Long> deptIdList = new ArrayList<>();

        // 获取子部门ID
        List<Long> subIdList = queryDetpIdList(deptId);
        getDeptTreeList(subIdList, deptIdList);

        return deptIdList;
    }

    /**
     * 递归
     */
    private void getDeptTreeList(List<Long> subIdList, List<Long> deptIdList) {
        for (Long deptId : subIdList) {
            List<Long> list = queryDetpIdList(deptId);
            if (list.size() > 0) {
                getDeptTreeList(list, deptIdList);
            }

            deptIdList.add(deptId);
        }
    }

    /**
     * 分页查询组织机构信息
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        String deptId = (String)params.get("deptId");
        String company = (String)params.get("company");
        String taxno = (String)params.get("taxno");
        IPage<SysDeptEntity> page = null;
        if (StringUtils.isNotBlank(taxno)) {
            page = this.page(new Query<SysDeptEntity>().getPage(params), new QueryWrapper<SysDeptEntity>()
                .eq(StringUtils.isNotBlank(taxno), "taxno", taxno).eq("org_type", "5").orderByDesc("create_date"));
        } else {
            page = this.page(new Query<SysDeptEntity>().getPage(params),
                new QueryWrapper<SysDeptEntity>().eq(StringUtils.isNotBlank(deptId), "parent_id", deptId)
                    .eq(StringUtils.isNotBlank(company), "company", company).in("org_type", "1", "5")
                    .orderByDesc("create_date"));
        }

        return new PageUtils(page);
    }

    @Override
    public SysDeptEntity queryDept(String company, String deptType) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectOne(new QueryWrapper<SysDeptEntity>().eq("company", company).eq("org_type", deptType));
    }

    @Override
    public void saveDept(SysDeptEntity dept) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        dept.setCreateDate(new Date());
        Aops.getSelf(this).insertDept(dept);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDept(SysDeptEntity dept) {
        baseMapper.insert(dept);
    }

    public void saveDeptList(List<SysDeptEntity> deptList) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).insertDeptList(deptList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDeptList(List<SysDeptEntity> deptList) {
        this.saveOrUpdateBatch(deptList);
    }

    public List<SysDeptEntity> queryDeptList() {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryDeptList();
    }

    @Override
    public void updateDept(SysDeptEntity dept) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).updateDeptId(dept);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDeptId(SysDeptEntity dept) {
        baseMapper.updateById(dept);
    }

    @Override
    public void deleteDept(Long id) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        baseMapper.deleteById(id);
    }

    @Override
    public SysDeptEntity queryDeptById(Long deptId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectById(deptId);
    }

    @Override
    public Integer queryDeptTaxNo(String taxno, String orgtype, String company, Long deptId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        Integer count = 0;
        if ("5".equals(orgtype)) {
            count = baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno).eq("org_type", orgtype)
                .ne(deptId != null, "dept_id", deptId));
        } else if ("1".equals(orgtype)) {
            count = baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("org_type", orgtype)
                .eq("company", company).ne(deptId != null, "dept_id", deptId));
        } else if ("8".equals(orgtype)) {
            count = baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno).eq("org_type", orgtype)
                .eq("company", company).ne(deptId != null, "dept_id", deptId));
        }

        return count;
    }

    @Override
    public int uploadDept(String datalist) {
        log.debug("导入数据：" + datalist);
        List<SysDeptEntity> list = new ArrayList<>();
        try {
            List<SysDeptEntity> deptList = JSON.parseArray(datalist, SysDeptEntity.class);
            if (deptList != null && deptList.size() > 0) {
                for (SysDeptEntity sysDeptEntity : deptList) {
                    sysDeptEntity.setDeptType(ManageConstants.DeptType.DEPT_TYPE_3.getCode());
                    sysDeptEntity.setOrgType(ManageConstants.OrgType.ORG_TYPE_5.getCode());
                    if (ManageConstants.CheckYesorNo.CHECK_YESORNO_Y.getCode()
                        .equals(sysDeptEntity.getIsCheckYesorno())) {
                        sysDeptEntity.setIsCheckYesorno(ManageConstants.CheckYesorNo.CHECK_YESORNO_1.getCode());
                    } else if (ManageConstants.CheckYesorNo.CHECK_YESORNO_N.getCode()
                        .equals(sysDeptEntity.getIsCheckYesorno())) {
                        sysDeptEntity.setIsCheckYesorno(ManageConstants.CheckYesorNo.CHECK_YESORNO_0.getCode());
                    }

                    if (ManageConstants.CollectYesorNo.COLLECT_YESORNO_Y.getCode()
                        .equals(sysDeptEntity.getIsCollectYesorno())) {
                        sysDeptEntity.setIsCollectYesorno(ManageConstants.CollectYesorNo.COLLECT_YESORNO_1.getCode());
                    } else if (ManageConstants.CollectYesorNo.COLLECT_YESORNO_N.getCode()
                        .equals(sysDeptEntity.getIsCollectYesorno())) {
                        sysDeptEntity.setIsCollectYesorno(ManageConstants.CollectYesorNo.COLLECT_YESORNO_0.getCode());
                    }

                    // 获取组织机构信息，判断是否存在
                    SysDeptEntity queryDept =
                        this.queryDeptTaxno(sysDeptEntity.getTaxno(), ManageConstants.OrgType.ORG_TYPE_5.getCode());
                    if (queryDept != null) {
                        return 1;
                    }
                    // 获取集团信息
                    SysDeptEntity deptCompany =
                        this.queryDept(sysDeptEntity.getCompany(), ManageConstants.DeptType.DEPT_TYPE_1.getCode());
                    if (deptCompany == null) {
                        return 2;
                    } else {
                        sysDeptEntity.setDeptId(deptCompany.getDeptId());
                        sysDeptEntity.setParentId(deptCompany.getDeptId());
                        sysDeptEntity.setLevelCode(deptCompany.getLevelCode());
                        sysDeptEntity.setAceId(deptCompany.getAceId());
                        sysDeptEntity.setAceKey(deptCompany.getAceKey());
                    }
                    list.add(this.toDept(sysDeptEntity));
                }
            }
            if (list.size() > 0) {
                this.saveDeptList(list);
            }
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 3;
        }

    }

    @Override
    public SysDeptEntity toDept(SysDeptEntity dept) {
        // 如果添加总部的话 orttype 只能是 1
        if (dept.getDeptId() == null) {
            dept.setOrgType(ManageConstants.OrgType.ORG_TYPE_1.getCode());
            dept.setParentId(0L);
            dept.setOrderNum(0);
            dept.setCompany(ManageConstants.ZXQY + dept.getCompany());
        } else {
            dept.setParentId(dept.getDeptId());
            dept.setDeptId(null);
        }
        // 中心企业
        if (ManageConstants.DeptType.DEPT_TYPE_0.getCode().equals(dept.getDeptType())) {
            // 中心企业
            dept.setOrgType(ManageConstants.OrgType.ORG_TYPE_0.getCode());
        } else if (ManageConstants.DeptType.DEPT_TYPE_1.getCode().equals(dept.getDeptType())) {
            dept.setOrgType(ManageConstants.OrgType.ORG_TYPE_1.getCode());
        } else if (ManageConstants.DeptType.DEPT_TYPE_3.getCode().equals(dept.getDeptType())) {
            dept.setOrgType(ManageConstants.OrgType.ORG_TYPE_5.getCode());
        }
        dept.setName(dept.getTaxname());
        dept.setCreateDate(new Date());
        dept.setUpdateDate(new Date());
        dept.setLevelCode(ManageConstants.LEVEL_CODE);
        if (ManageConstants.IsModel.IS_MODEL_1.getCode().equals(dept.getIsModel())) {
            dept.setCollectOptType(ManageConstants.OptType.OPT_TYPE_1.getCode());
        }
        dept.setDownOptType(ManageConstants.OptType.OPT_TYPE_0.getCode());
        dept.setDownKeyType(dept.getCollectKeyType());
        dept.setValidType(ManageConstants.ValidType.VALID_TYPE_0.getCode());
        dept.setBussinessType(ManageConstants.BussinessType.BUSSINESS_TYPE_1.getCode());
        dept.setInitMonth(ManageConstants.INIT_MONTH);
        dept.setInvSpec(ManageConstants.InvSpec.INV_SPEC_0.getCode());
        dept.setTaxCollectStatus(ManageConstants.TaxCollectStatus.TAX_COLLECT_STATUS_0.getCode());
        if (StringUtils.isBlank(dept.getArea()) && StringUtils.isNotBlank(dept.getArea())) {
            this.getArea(dept.getTaxno());
        }
        return dept;
    }

    /**
     * 根据税号获取地区编码
     *
     * @param taxno
     * @return
     */
    private String getArea(String taxno) {
        // 判断税号位数，
        String area = null;
        if (taxno.length() == 18) {
            String fourarea = taxno.substring(2, 6);
            if ("2102".equals(fourarea) || "3302".equals(fourarea) || "3502".equals(fourarea) || "3702".equals(fourarea)
                || "4403".equals(fourarea)) {
                return fourarea;
            } else {
                String twoarea = taxno.substring(4, 6);
                area = fourarea.replace(twoarea, "00");
                return area;
            }
        }
        if (taxno.length() == 15 || taxno.length() == 20) {
            String fourarea = taxno.substring(0, 4);
            if ("2102".equals(fourarea) || "3302".equals(fourarea) || "3502".equals(fourarea) || "3702".equals(fourarea)
                || "4403".equals(fourarea)) {
                return fourarea;
            } else {
                String twoarea = taxno.substring(2, 4);
                area = fourarea.replace(twoarea, "00");
                return area;
            }
        }
        return area;
    }

    @Override
    public String getTaxManage(SysDeptEntity deptEntity, String functionNo, String optType) {
        FunctionModel functionModel = new FunctionModel();
        functionModel.setFunctionNo(functionNo);
        functionModel.setOptType(optType);
        functionModel.setBussinessType(ManageConstants.BussinessType.BUSSINESS_TYPE_1.getCode());
        functionModel.setValidType(ManageConstants.ValidType.VALID_TYPE_0.getCode());
        functionModel.setKeyType(deptEntity.getCollectKeyType());
        if (ManageConstants.FunctionNo.FUNCTION_NO_02.getCode().equals(functionNo)) {
            functionModel.setInitMonth("");
            functionModel.setInvSpec("");
        } else {
            functionModel.setInitMonth(deptEntity.getInitMonth());
            functionModel.setInvSpec(deptEntity.getInvSpec());
        }
        try {
            ReturnModel returnModel =
                taxManageService.getKeyTaxManage(functionModel, deptEntity.getArea(), deptEntity.getTaxno());
            if (ManageConstants.OptType.OPT_TYPE_0.getCode().equals(optType)) {
                optType = ManageConstants.OptType.OPT_TYPE_1.getCode();
            }
            if (ManageConstants.SUCCESS_CODE.equals(returnModel.getCode())) {
                // 调用修改接口修改相应信息
                deptEntity.setUpdateDate(new Date());
                if (ManageConstants.FunctionNo.FUNCTION_NO_02.getCode().equals(functionNo)) {
                    deptEntity.setCollectOptType(optType);
                } else {
                    deptEntity.setDownOptType(optType);
                    if (ManageConstants.OptType.OPT_TYPE_2.getCode().equals(optType)) {
                        deptEntity.setCollectStatus(ManageConstants.CollectStatus.COLLECT_STATUS_0.getCode());
                    } else {
                        deptEntity.setCollectStatus(ManageConstants.CollectStatus.COLLECT_STATUS_1.getCode());
                    }
                }
                Aops.getSelf(this).updateDept(deptEntity);
                return ManageConstants.SUCCESS_CODE;
            } else {
                return ManageConstants.ERROR_CODE;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ManageConstants.ERROR_CODE;
        }
    }

    @Override
    public ReturnTokenModel getToken(Map<String, Object> params) {
        String area = (String)params.get("area");
        ReturnTokenModel returnTokenModel;
        VersionModel versionModel = this.getVersion(area);
        if (versionModel == null) {
            returnTokenModel = new ReturnTokenModel();
            returnTokenModel.setCode(9997);
            returnTokenModel.setMessage("地区编码不正确：" + area);
            return returnTokenModel;
        }
        String taxno = (String)params.get("taxno");
        int index = (int)params.get("index");
        String ip = (String)params.get("ip");
        String password = (String)params.get("password");
        if (index == 0 || StringUtils.isBlank(ip)) {
            returnTokenModel = new ReturnTokenModel();
            returnTokenModel.setCode(9996);
            returnTokenModel.setMessage("证书IP或者证书槽位为空，证书ip：" + ip + " , 证书槽位：" + index);
            return returnTokenModel;
        }
        return authTokenService.getToken(taxno, index, ip, password, versionModel.getUrl(), versionModel.getYmbb(),
            versionModel.isGmType());
    }

    public SysDeptEntity queryDeptTaxno(String taxno, String orgType) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectOne(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno).eq("org_type", orgType));
    }

    /**
     * 查询 请求地址和版本号
     *
     * @param area
     *            地区编码
     * @return 请求地址和版本号
     */
    public VersionModel getVersion(String area) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.getVersion(area);
    }
}
