package com.energy.manage.service.service.company.impl;


import cn.hutool.core.bean.BeanUtil;
import com.energy.manage.common.base.BaseServiceImpl;
import com.energy.manage.common.constant.Constants;
import com.energy.manage.common.constant.redis.ManagerRedisKeyConstant;
import com.energy.manage.common.enums.DeleteStatusEnum;
import com.energy.manage.common.enums.IdPrefixEnum;
import com.energy.manage.common.enums.TypeRelationEnum;
import com.energy.manage.common.po.company.WindCompanyPO;
import com.energy.manage.common.po.system.SysPermissionPO;
import com.energy.manage.common.po.system.SysRolePermissionPO;
import com.energy.manage.common.po.system.SysUserInfoPO;
import com.energy.manage.common.util.IdGeneratorUtil;
import com.energy.manage.service.domain.dto.company.*;
import com.energy.manage.service.domain.dto.system.RoleUpdateOrganizationDto;
import com.energy.manage.service.domain.dto.windrelation.WindRelationDelDto;
import com.energy.manage.service.domain.dto.windrelation.WindRelationDto;
import com.energy.manage.service.domain.vo.company.WindCompanyPageVo;
import com.energy.manage.service.domain.vo.company.WindCompanyVo;
import com.energy.manage.service.domain.vo.system.PermissionVo;
import com.energy.manage.service.mappers.company.WindCompanyMapper;
import com.energy.manage.service.mappers.system.SysPermissionMapper;
import com.energy.manage.service.mappers.system.SysRolePermissionMapper;
import com.energy.manage.service.service.cache.CacheService;
import com.energy.manage.service.service.company.WindCompanyService;
import com.energy.manage.service.service.system.SysOrganizationAuthService;
import com.energy.manage.service.service.system.SysPermissionService;
import com.energy.manage.service.service.windrelation.WindRelationService;
import com.energy.manage.service.util.BeanMapUtils;
import com.energy.manage.service.util.SplitUtil;
import com.energy.manage.service.util.TreeUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class WindCompanyServiceImpl extends BaseServiceImpl<WindCompanyPO> implements WindCompanyService {

    @Autowired
    private CacheService cacheService;

    @Autowired
    private WindRelationService windRelationService;

    @Autowired
    private WindCompanyMapper windCompanyMapper;

    @Autowired
    private SysOrganizationAuthService sysOrganizationAuthService;

    @Autowired
    private SysPermissionService permissionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addCompany(WindCompanyDto dto,Integer roleId,Integer userId) {
        WindCompanyPO po = new WindCompanyPO();
        BeanUtil.copyProperties(dto, po);
        po.setCreateTime(new Date());
        po.setUpdateTime(new Date());
        po.setState(Constants.GLOBAL_IN_USE);
        po.setDelState(DeleteStatusEnum.NODELETE.getCode());
        po.setCompanyCode(IdPrefixEnum.COMPANY_NUMBER.getCode().concat(IdGeneratorUtil.zeroFillUtil(cacheService.incr(ManagerRedisKeyConstant.build(ManagerRedisKeyConstant.IDGENERATOR_CONSTANTS_KEY, IdPrefixEnum.COMPANY_NUMBER.getCode())))));

        if (windCompanyMapper.insertUseGeneratedKeys(po) <= 0) {
            return false;
        }

        // 处理创建企业对应角色权限
        RoleUpdateOrganizationDto.OrganizationCode organizationCode = new RoleUpdateOrganizationDto.OrganizationCode();
        List<RoleUpdateOrganizationDto.OrganizationCode> organizationCodes = Lists.newArrayList();
        organizationCode.setCodeNumber(po.getCompanyCode());
        organizationCode.setCodeType(TypeRelationEnum.COMPANY_NUMBER.getCode());
        organizationCodes.add(organizationCode);
        permissionService.updateRoleOrganization(roleId,organizationCodes,userId,0);

        return this.createWindRelation(dto, po);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delCompany(WindCompanyDelDto dto) {
        WindCompanyPO po = new WindCompanyPO();
        po.setDelState(DeleteStatusEnum.DELETE.getCode());
        Example queryExample = new Example(WindCompanyPO.class);
        Example.Criteria criteria = queryExample.createCriteria();
        criteria.andEqualTo("companyCode", dto.getCompanyCode());
        if (windCompanyMapper.updateByExampleSelective(po, queryExample) <= 0) {
            return false;
        }

        // 删除数据权限
        sysOrganizationAuthService.delSysOrganizationAuth(dto.getCompanyCode(),TypeRelationEnum.COMPANY_NUMBER.getCode());

        // 删除树形结构
        WindRelationDelDto windRelationDelDto = new WindRelationDelDto();
        windRelationDelDto.setCodeNumber(dto.getCompanyCode());
        windRelationDelDto.setType(TypeRelationEnum.COMPANY_NUMBER.getCode());
        return windRelationService.delWindRelation(windRelationDelDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStateCompany(WindCompanyStateDto dto) {

        WindCompanyPO po = new WindCompanyPO();
        po.setState(dto.getState());
        Example queryExample = new Example(WindCompanyPO.class);
        Example.Criteria criteria = queryExample.createCriteria();
        criteria.andEqualTo("companyCode", dto.getCompanyCode());

        return windCompanyMapper.updateByExampleSelective(po, queryExample) > 0;
    }

    /**
     * 创建关系数据
     *
     * @param windCompanyDto
     * @return
     */
    private boolean createWindRelation(WindCompanyDto windCompanyDto, WindCompanyPO po) {

        WindRelationDto windRelationDto = new WindRelationDto();
        windRelationDto.setCodeNumber(po.getCompanyCode());
        windRelationDto.setCodeName(po.getCompanyName());
        windRelationDto.setParentCode(windCompanyDto.getParentCode());
        windRelationDto.setType(TypeRelationEnum.COMPANY_NUMBER.getCode());

        return windRelationService.createWindRelation(windRelationDto);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCompany(WindCompanyUpdateDto dto) {
        WindCompanyPO po = new WindCompanyPO();
        BeanUtil.copyProperties(dto, po);
        Example queryExample = new Example(WindCompanyPO.class);
        Example.Criteria criteria = queryExample.createCriteria();
        criteria.andEqualTo("companyCode", dto.getCompanyCode());
        if (windCompanyMapper.updateByExampleSelective(po, queryExample) <= 0) {
            return false;
        }
        WindRelationDto windRelationDto = new WindRelationDto();
        windRelationDto.setCodeName(dto.getCompanyName());
        windRelationDto.setCodeNumber(dto.getCompanyCode());
        return windRelationService.updateWindRelationName(windRelationDto);

    }

    @Override
    public List<Map<String, Object>> getAllWindCompany(Integer state,String companyName,Integer roleId,Integer userId) {
        return windRelationService.getWindRelationCompany(state,companyName,roleId,userId);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateWindCompanyBySort(WindCompanyCustomDto dto) {
        return windCompanyMapper.updateWindCompanySort(dto.getWindCompanyUpdateSortList()) > 0;
    }


    @Override
    public WindCompanyVo getWindCompany(WindCompanyDelDto windCompanyDelDto) {
        WindCompanyPO po = new WindCompanyPO();
        po.setCompanyCode(windCompanyDelDto.getCompanyCode());
        WindCompanyPO windCompanyPO =  windCompanyMapper.selectOne(po);
        if(windCompanyPO == null){
            return null;
        }
        WindCompanyVo windCompanyVo = new WindCompanyVo();
        BeanUtil.copyProperties(windCompanyPO,windCompanyVo);
        return windCompanyVo;
    }

    @Override
    public WindCompanyPO getWindCompanyByCompanyName(WindCompanyDto dto) {
        Example queryExample = new Example(WindCompanyPO.class);
        Example.Criteria criteria = queryExample.createCriteria();
        criteria.andEqualTo("companyName", dto.getCompanyName());
        criteria.andEqualTo("delState", DeleteStatusEnum.NODELETE.getCode());
        return windCompanyMapper.selectOneByExample(queryExample);
    }
}
