package com.xxfc.platform.vehicle.biz;

import cn.hutool.core.bean.BeanUtil;
import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.google.common.collect.Lists;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.RedisKey;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import com.xxfc.platform.vehicle.entity.Area;
import com.xxfc.platform.vehicle.entity.BranchCompany;
import com.xxfc.platform.vehicle.entity.BranchCompanyStockInfo;
import com.xxfc.platform.vehicle.entity.SysRegion;
import com.xxfc.platform.vehicle.mapper.BranchCompanyMapper;
import com.xxfc.platform.vehicle.pojo.BranchCompanyVo;
import com.xxfc.platform.vehicle.pojo.CompanyDetail;
import com.xxfc.platform.vehicle.pojo.CompanySearchDTO;
import com.xxfc.platform.vehicle.pojo.dto.BranchCompanyFindDTO;
import com.xxfc.platform.vehicle.pojo.dto.BranchCompanyListDTO;
import com.xxfc.platform.vehicle.pojo.vo.BranComanyLeaderVo;
import com.xxfc.platform.vehicle.pojo.vo.BranchCompanyListVO;
import com.xxfc.platform.vehicle.util.excel.ExcelImport;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.github.wxiaoqi.security.auth.common.constatns.CommonConstants.DATA_ALL_FALSE;
import static com.xxfc.platform.vehicle.constant.DbColumnConstant.COMPANY_ZONE_ID;
import static com.xxfc.platform.vehicle.constant.DbColumnConstant.ID;
import static com.xxfc.platform.vehicle.constant.RedisKey.BRANCH_COMPANY_CACHE_DATAZONE;

@Service
@Slf4j
public class BranchCompanyBiz extends BaseBiz<BranchCompanyMapper, BranchCompany> implements UserRestInterface {

    public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
    public static final DateTimeFormatter YEARMONTH_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM");

    @Autowired
    private RedisTemplate customRedisTemplate;

    @Autowired
    private SysRegionBiz sysRegionBiz;

    @Autowired
    UserFeign userFeign;

    @Autowired
    private AreaBiz areaBiz;

    @Override
    public UserFeign getUserFeign() {
        return userFeign;
    }


    @Value("${branchCompanyPic.baseUploadPath}")
    private String baseUploadPath;

    @Autowired
    private VehicleBiz vehicleBiz;


    /**
     * 按主键获取公司
     *
     * @param id
     * @return
     */
    public BranchCompany getById(Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

    public List<BranchCompany> selectByZoneId(Integer zoneId) {
        if (zoneId == null) {
            return null;
        }
        UserDTO userDTO = getAdminUserInfo();
        if (userDTO == null) {
            return null;
        }
        Map<String, Object> map = new HashedMap<>();
        map.put("zoneId", zoneId);
        List<Integer> branchCompanies = Lists.newArrayList();
        if (DATA_ALL_FALSE.equals(userDTO.getDataAll())) { //不能获取全部数据
            branchCompanies = vehicleBiz.dataCompany(userDTO.getDataZone(), userDTO.getDataCompany());
        }
        map.put("ids", branchCompanies);
        return mapper.selectByZoneId(map);
    }

    /**
     * 获取公司信息
     *
     * @param id
     * @return
     */
    @Cache(key = RedisKey.BRANCH_COMPANY_CACHE + "{1}")
    public CompanyDetail getDetailById(Integer id) {
        BranchCompany branchCompany = this.getById(id);
        CompanyDetail detail = null;
        if (branchCompany != null) {
            List<SysRegion> sysRegions = sysRegionBiz.getRegionsByCodes(new ArrayList<Long>() {{
                if(branchCompany.getAddrProvince() != null) {
                    add(Long.valueOf(branchCompany.getAddrProvince()));
                }
                if(branchCompany.getAddrCity() != null) {
                    add(Long.valueOf(branchCompany.getAddrCity()));
                }
                if(branchCompany.getAddrTown() != null) {
                    add(Long.valueOf(branchCompany.getAddrTown()));
                }
            }});
            detail = BeanUtil.toBean(branchCompany, CompanyDetail.class);
            detail.setSysRegions(sysRegions);
        }
        return detail;
    }

    public Boolean exits(Integer id) {
        BranchCompany param = new BranchCompany();
        param.setId(id);
        return mapper.selectCount(param) > 0;
    }

    /**
     * 转换为vo类
     *
     * @param branchCompanies
     * @returns
     */
    private List<BranchCompanyVo> branchCompany2VO(List<BranchCompany> branchCompanies) {
        List<BranchCompanyVo> branchCompanyVoList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(branchCompanies)) {
            for (BranchCompany branchCompany : branchCompanies) {
                BranchCompanyVo branchCompanyVo = new BranchCompanyVo();
                BeanUtils.copyProperties(branchCompany, branchCompanyVo);
                branchCompanyVoList.add(branchCompanyVo);
            }
        }
        return branchCompanyVoList;
    }

    public PageDataVO<BranchCompany> getAll(Integer page, Integer limit, Integer addrProvince, Integer addrCity,
                                            Integer addrTown, Integer zoneId, UserDTO userDTO) {
        Example example = new Example(BranchCompany.class);
        Example.Criteria criteria = example.createCriteria();
        String provinceIds = "";
        if (Objects.nonNull(zoneId)) {
            Area area = areaBiz.selectById(zoneId);
            provinceIds = area.getProvinceIds();
        }
        if (StringUtils.isNotEmpty(provinceIds)) {
            List<String> provinceIdList = Arrays.asList(provinceIds.split(","));
            if (Objects.nonNull(addrProvince)) {
                if (provinceIdList.contains(String.valueOf(addrProvince))) {
                    criteria.andEqualTo("addrProvince", addrProvince);
                } else {
                    return new PageDataVO<BranchCompany>();
                }
            } else {
                criteria.andIn("addrProvince", provinceIdList);
            }
        } else {
            if (addrProvince != null) {
                criteria.andEqualTo("addrProvince", addrProvince);
            }
        }
        if (addrCity != null) {
            criteria.andEqualTo("addrCity", addrCity);
        }
        if (addrTown != null) {
            criteria.andEqualTo("addrTown", addrTown);
        }
        if (userDTO != null && DATA_ALL_FALSE.equals(userDTO.getDataAll())) {
            if (StringUtils.isNotBlank(userDTO.getDataZone())) {
                criteria.andIn(COMPANY_ZONE_ID, userDTO.dataZone2List());
            }
            if (StringUtils.isNotBlank(userDTO.getDataCompany())) {
                criteria.andIn(ID, userDTO.dataCompany2List());
            }
        }
        example.setOrderByClause("`id` desc");
        PageHelper.startPage(page, limit);
        PageInfo<BranchCompany> branchCompanyPageInfo = new PageInfo<>(mapper.selectByExample(example));
        return PageDataVO.pageInfo(branchCompanyPageInfo);
    }

    public PageDataVO<BranchCompany> search(CompanySearchDTO vo) {
        PageHelper.startPage(vo.getPage(), vo.getLimit());
        PageInfo<BranchCompany> branchCompanyPageInfo = new PageInfo<>(mapper.search(vo.getLon(), vo.getLat(), vo.getAddrCity(), vo.getState(), vo.getIsShow(), vo.getIsDel()));
        return PageDataVO.pageInfo(branchCompanyPageInfo);
    }


    @Cache(key = RedisKey.BRANCH_COMPANY_CACHE_ALL)
    public List<BranchCompany> getAll() {
        Example example = new Example(BranchCompany.class);
        example.createCriteria().andEqualTo("isDel", 0);
        return mapper.selectByExample(example);
    }

    /**
     * 增加公司，返回id
     *
     * @param branchCompanyVo
     * @return
     */
    @CacheClear(pre = RedisKey.BRANCH_COMPANY_CACHE)
    public Integer add(BranchCompanyVo branchCompanyVo) {
        BranchCompany branchCompany = new BranchCompany();
        BeanUtils.copyProperties(branchCompanyVo, branchCompany);
        mapper.insertSelective(branchCompany);
        return branchCompany.getId();
    }

    @CacheClear(pre = RedisKey.BRANCH_COMPANY_CACHE)
    public void del(Integer id) {
        mapper.deleteByPrimaryKey(id);
    }

    /**
     * 更新公司信息
     *
     * @param branchCompany
     * @return
     */
    @CacheClear(pre = RedisKey.BRANCH_COMPANY_CACHE)
    public Integer update(BranchCompany branchCompany) {
        return mapper.updateByPrimaryKeySelective(branchCompany);
    }

    /**
     * 写入上传文件，返回相对路径
     *
     * @param file
     * @return
     */
    public RestResponse<String> uploadCompanyPic(MultipartFile file) throws Exception {
        //创建本日存放目录
        DateTime now = DateTime.now();
        String dirPathToday = File.separator + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        String redisNoKey = RedisKey.UPLOAD_FILE_NO_PREFIX + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        Long no = customRedisTemplate.opsForValue().increment(redisNoKey);
        if (no.equals(1l)) {
            customRedisTemplate.expire(redisNoKey, 1, TimeUnit.DAYS);
        }
        String fileName = file.getOriginalFilename();
        String realFileRelPath = dirPathToday + File.separator + no + fileName.substring(fileName.lastIndexOf("."));
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath;
        //将文件写入指定位置 FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath));
        return RestResponse.suc(realFileRelPath);
    }

    @Cache(key = BRANCH_COMPANY_CACHE_DATAZONE)
    public List<BranchCompany> dataCompany(String dataZone) {
        if (StringUtils.isBlank(dataZone)) {
            return new ArrayList<BranchCompany>();
        }
        List<Integer> zoneIds = Arrays.asList(dataZone.split(",")).parallelStream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());
        Example example = new Example(BranchCompany.class);
        example.createCriteria().andIn("zoneId", zoneIds);
        List<BranchCompany> zoneCompanys = selectByExample(example);
        return zoneCompanys;

    }

    public RestResponse<String> importExcel(MultipartFile multipartfile, HttpServletRequest request) {
        try {
            List<String[]> readExcel = ExcelImport.getExcelData(multipartfile);
            if (readExcel.size() < 1) {
                return RestResponse.codeAndMessage(1001, "导入不能没数据！！！");
            }
            List<BranchCompanyStockInfo> list = new ArrayList<>();
            for (int i = 1; i < readExcel.size(); i++) {
                String[] str = readExcel.get(i);
                BranchCompany branchCompany = new BranchCompany();
                branchCompany.setName(str[0]);
                branchCompany = mapper.selectOne(branchCompany);
                if (branchCompany != null) {
                    BranchCompany branchCompany1 = new BranchCompany();
                    if (str.length > 1) {
                        branchCompany1.setLeader(str[1]);
                    }
                    if (str.length > 2) {
                        branchCompany1.setLeaderContactInfo(str[2]);
                    }
                    if (branchCompany1 != null && (StringUtils.isNotBlank(branchCompany1.getLeader()) || StringUtils.isNotBlank(branchCompany1.getLeaderContactInfo()))) {
                        branchCompany1.setId(branchCompany.getId());
                        mapper.updateByPrimaryKeySelective(branchCompany1);
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.codeAndMessage(10001, "网络异常！");
        }
        return RestResponse.suc();
    }

    public List<BranchCompany> getListByUser(UserDTO userDTO) {
        if (userDTO != null && DATA_ALL_FALSE.equals(userDTO.getDataAll())) {
            Example example = new Example(BranchCompany.class);
            Example.Criteria criteria = example.createCriteria();
            if (StringUtils.isNotBlank(userDTO.getDataZone())) {
                criteria.andIn(COMPANY_ZONE_ID, userDTO.dataZone2List());
            }
            if (StringUtils.isNotBlank(userDTO.getDataCompany())) {
                criteria.andIn(ID, userDTO.dataCompany2List());
            }
            example.setOrderByClause("`id` asc");
            return mapper.selectByExample(example);
        }
        return getAll();

    }

    /**
     * 通过片区片区和分公司id获取对应的城市信息
     *
     * @param zoneList
     * @param companyList
     * @return
     */
    public Set<Integer> getCity(String zoneList, String companyList) {
        List<Integer> list = vehicleBiz.dataCompany(zoneList, companyList);
        if (CollectionUtils.isEmpty(list)) {
            return new HashSet<>();
        }
        Example exa = new Example(BranchCompany.class);
        Example.Criteria criteria = exa.createCriteria();
        criteria.andIn("id", list);
        List<BranchCompany> result = mapper.selectByExample(exa);
        return result.parallelStream().map(BranchCompany::getAddrCity).collect(Collectors.toSet());


    }

    public List<Integer> selectCompanyIdsByAreaId(Integer areaId) {
        return mapper.findCompanyIdsByAreaId(areaId);
    }

    public Map<Integer, BranComanyLeaderVo> findCompanyLeaderMapByIds(List<Integer> companyIds) {
        Map<Integer, BranComanyLeaderVo> companyIdAndLeaderMap = new HashMap<>(companyIds.size());
        List<BranchCompany> branchCompanies = mapper.selectByIdList(companyIds);
        if (CollectionUtils.isEmpty(branchCompanies)) {
            return companyIdAndLeaderMap;
        }
        return branchCompanies.stream().collect(Collectors.toMap(BranchCompany::getId, branchCompany -> {
            BranComanyLeaderVo branComanyLeaderVo = new BranComanyLeaderVo();
            BeanUtils.copyProperties(branchCompany, branComanyLeaderVo);
            return branComanyLeaderVo;
        }));
    }

    public PageDataVO<BranchCompanyListVO> findBranchCompanyWithPage(BranchCompanyFindDTO branchCompanyFindDTO) {
        PageDataVO<BranchCompanyListVO> pageDataVO = new PageDataVO<>();
        PageDataVO<BranchCompanyListDTO> dataVO = PageDataVO.pageInfo(branchCompanyFindDTO.getPage(), branchCompanyFindDTO.getLimit(), () -> mapper.findBranchCompanys(branchCompanyFindDTO.getAddrProvince(), branchCompanyFindDTO.getAddrCity(),branchCompanyFindDTO.getName()));
        List<BranchCompanyListDTO> data = dataVO.getData();
        if (CollectionUtils.isEmpty(data)) {
            return pageDataVO;
        }
        List<BranchCompanyListVO> branchCompanyListVOS = new ArrayList<>();
        BranchCompanyListVO branchCompanyListVO;
        for (BranchCompanyListDTO companyListDTO : data) {
            branchCompanyListVO = new BranchCompanyListVO();
            BeanUtils.copyProperties(companyListDTO, branchCompanyListVO);
            branchCompanyListVOS.add(branchCompanyListVO);
        }
        pageDataVO.setData(branchCompanyListVOS);
        pageDataVO.setPageSize(dataVO.getPageSize());
        pageDataVO.setPageNum(dataVO.getPageNum());
        pageDataVO.setTotalPage(dataVO.getTotalPage());
        pageDataVO.setTotalCount(dataVO.getTotalCount());
        return pageDataVO;
    }
    public  List<JSONObject> getList(){
     return  mapper.getList();
    }

    public ObjectRestResponse branchCompans() {
        UserDTO userDTO = getAdminUserInfo();
        List<BranchCompany> list;
        if (userDTO != null&&userDTO.getDataAll() == DATA_ALL_FALSE) {
            List<Integer> branchCompanies = vehicleBiz.dataCompany(userDTO.getDataZone(), userDTO.getDataCompany());
            list = mapper.selectByIdList(branchCompanies);
        }else {
            list=getAll();
        }
        return  ObjectRestResponse.succ(list);
    }

    public List<Integer> getCompanyIds(String dataZone ,String dataCompany) {
        return vehicleBiz.dataCompany(dataZone, dataCompany);
    }

    @CacheClear(pre = RedisKey.BRANCH_COMPANY_CACHE_ALL)
    public ObjectRestResponse delCompanyByBaseId(Integer id) {
        Example example = new Example(BranchCompany.class);
        example.createCriteria().andEqualTo("companyBaseId", id);
        example.createCriteria().andEqualTo("isDel", 0);
        BranchCompany branchCompany = mapper.selectOneByExample(example);
        if(branchCompany == null) {
            return ObjectRestResponse.createFailedResult(ResCode.BRANCH_COMPANY_UNEXIST.getCode(), ResCode.BRANCH_COMPANY_UNEXIST.getDesc());
        }
        branchCompany.setIsDel(1);
        updateSelectiveByIdRe(branchCompany);
        return ObjectRestResponse.succ();
    }

    public Map<Integer, String> selectCompanyMap() {
        Example example = new Example(BranchCompany.class);
        example.createCriteria().andEqualTo("isDel", 0);
        List<BranchCompany> branchCompanies = mapper.selectByExample(example);
        if (CollectionUtils.isEmpty(branchCompanies)){
            return Collections.EMPTY_MAP;
        }
      return branchCompanies.stream().collect(Collectors.toMap(BranchCompany::getId,BranchCompany::getName));
    }
}
