package com.cool.store.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.RegionDao;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.request.LicenseListRequest;
import com.cool.store.request.SubmitLicenseRequest;
import com.cool.store.request.license.BusinessLicenseRequest;
import com.cool.store.request.license.FoodLicenseRequest;
import com.cool.store.response.GetStoreInfoByCodeResponse;
import com.cool.store.response.LicenseListResponse;
import com.cool.store.response.SubmitLicenseResponse;
import com.cool.store.service.*;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.StringUtil;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.utils.poi.constant.Constants;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.ShopAuditInfoVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ApplyLicenseServiceImpl implements ApplyLicenseService {

    @Resource
    ApplyLicenseMapper applyLicenseMapper;

    @Resource
    ShopAuditInfoMapper shopAuditInfoMapper;

    @Resource
    private EnterpriseUserDAO userDAO;

    @Resource
    private RegionDao regionDao;

    @Resource
    private RegionMapper regionMapper;

    @Resource
    ShopStageInfoDAO shopStageInfoDAO;

    @Resource
    EnterpriseUserMapper userMapper;

    @Resource
    CoolStoreStartFlowService coolStoreStartFlowService;

    @Resource
    ShopInfoMapper shopInfoMapper;

    @Resource
    PreparationService preparationService;

    @Resource
    EnterpriseUserRoleMapper enterpriseUserRoleMapper;

    @Resource
    UserAuthMappingMapper userAuthMappingMapper;

    @Resource
    CommonService commonService;

    @Resource
    LineInfoMapper lineInfoMapper;

    @Resource
    RedisUtilPool redisUtilPool;

    @Resource
    private SystemBuildingShopMapper systemBuildingShopMapper;

    @Resource
    EnterpriseUserMapper enterpriseUserMapper;

    @Resource
    UserAuthMappingService userAuthMappingService;


    @Override
    public Boolean submitBusinessLicense(BusinessLicenseRequest request, PartnerUserInfoVO user) {
        log.info("submitBusinessLicense request：{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            return false;
        }
        String lockKey = "submitBusinessLicense:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = Boolean.FALSE;
        acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.ONE_SECONDS);
        if (!acquired) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        //防止一直在页面提交
        LicenseTransactDO license = applyLicenseMapper.selectByShopId(request.getShopId());
        LicenseTransactDO licenseTransactDO = request.toLicenseTransactDO(license);
        if (licenseTransactDO.getId() == null) {
            applyLicenseMapper.insertSelective(licenseTransactDO);
        } else {
            applyLicenseMapper.updateByPrimaryKey(licenseTransactDO);
        }
        if (Constants.ONE_INTEGER.equals(request.getSubmitStatus())) {
            shopStageInfoDAO.updateShopStageAndAuditInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_33, null);
            preparationService.licenseCompleted(request.getShopId());
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean submitFoodLicense(FoodLicenseRequest request, PartnerUserInfoVO user) {
        log.info("submitBusinessLicense request：{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            return false;
        }
        String lockKey = "submitBusinessLicense:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = Boolean.FALSE;
        acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.ONE_SECONDS);
        if (!acquired) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        //防止一直在页面提交
        LicenseTransactDO license = applyLicenseMapper.selectByShopId(request.getShopId());
        LicenseTransactDO licenseTransactDO = request.toLicenseTransactDO(license);
        if (licenseTransactDO.getId() == null) {
            applyLicenseMapper.insertSelective(licenseTransactDO);
        } else {
            applyLicenseMapper.updateByPrimaryKey(licenseTransactDO);
        }
        if (Constants.ONE_INTEGER.equals(request.getSubmitStatus())) {
            shopStageInfoDAO.updateShopStageAndAuditInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_43, null);
            preparationService.licenseCompleted(request.getShopId());
        }
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitLicense(SubmitLicenseRequest request, PartnerUserInfoVO user) {
        log.info("submitLicense request：{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            return false;
        }
        String lockKey = "submitLicense:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = Boolean.FALSE;
        acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.ONE_SECONDS);
        if (!acquired) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        LicenseTransactDO licenseTransactDO = request.toLicenseTransactDO();
        //防止一直在页面提交
        if (licenseTransactDO.getId() == null) {
            LicenseTransactDO license = applyLicenseMapper.selectByShopId(request.getShopId());
            if (license != null) {
                licenseTransactDO.setId(license.getId());
            }
        }
        if (request.getId() == null) {
            applyLicenseMapper.insertSelective(licenseTransactDO);
        } else {
            licenseTransactDO.setId(request.getId());
            applyLicenseMapper.updateByPrimaryKeySelective(licenseTransactDO);
        }
        if (Constants.ONE_INTEGER.equals(request.getSubmitStatus())) {
            ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
            shopAuditInfoDO.setShopId(request.getShopId());
            shopAuditInfoDO.setAuditType(AuditTypeEnum.LICENSE_APPROVAL.getCode());
            shopAuditInfoDO.setSubmittedUserId(user.getOpenid());
            shopAuditInfoDO.setSubmittedUserName(user.getUsername());
            shopAuditInfoDO.setDataType(0);
            shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
            shopStageInfoDAO.updateShopStageAndAuditInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_43, null);
            ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
            LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
            Map<String, String> requestMap = new HashMap<>();
            requestMap.put("shopId", String.valueOf(request.getShopId()));
            requestMap.put("storeName", shopInfoDO.getShopName());
            requestMap.put("partnerName", lineInfoDO.getUsername());
            requestMap.put("partnerMobile", lineInfoDO.getMobile());
            requestMap.put("lineId", String.valueOf(lineInfoDO.getId()));
            log.info("submitLicense SMS requestMap:{}", JSONObject.toJSONString(requestMap));
            List<String> sendUsers = new ArrayList<>();
            //如果没有督导，则发送给管辖此区域的所有战区经理
            if (StringUtil.isBlank(shopInfoDO.getSupervisorUserId())) {
                Long regionId = shopInfoDO.getRegionId();
                List<UserAuthMappingDO> userAuthByMappingIds = userAuthMappingMapper.getUserAuthByMappingIds(Collections.singletonList(String.valueOf(regionId)));
                if (CollectionUtils.isNotEmpty(userAuthByMappingIds)) {
                    List<String> sendUserIds = userAuthByMappingIds.stream().map(UserAuthMappingDO::getUserId).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(sendUserIds)) {
                        sendUsers = enterpriseUserRoleMapper.getUserIdsByRoleIds(Collections.singletonList("130000000"), sendUserIds);
                    }
                }
            } else {
                sendUsers.add(shopInfoDO.getSupervisorUserId());
            }
            if (CollectionUtils.isEmpty(sendUsers)) {
                log.info("未找到可发送工作通知的人员");
                return true;
            }
            //commonService.sendMessage(sendUsers, MessageEnum.MESSAGE_17, requestMap);
        }
        return true;
    }


    @Override
    public SubmitLicenseResponse getDefault(Long shopId) {
        //1.如果已经提交过证照信息，直接查询后组装数据
        LicenseTransactDO result = applyLicenseMapper.selectByShopId(shopId);
        SubmitLicenseResponse submitLicenseResponse = new SubmitLicenseResponse();
        if (Objects.nonNull(result)) {
            submitLicenseResponse = SubmitLicenseResponse.from(result);
        }
        ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
        if (shopInfoDO!=null&&shopInfoDO.getSupervisorUserId()!=null){
            EnterpriseUserDO user = enterpriseUserMapper.getUserInfoById(shopInfoDO.getSupervisorUserId());
            submitLicenseResponse.setApprover(user.getName());
        }
        //3.既没有提交数据，也没有在鲜丰端查到证照信息，则返回空自由填写
        return submitLicenseResponse;
    }

    public SubmitLicenseResponse.StoreDocument toStoreDocument(GetStoreInfoByCodeResponse.StoreDocument storeDocument) {
        SubmitLicenseResponse.StoreDocument submitLicenseResponse = new SubmitLicenseResponse.StoreDocument();
        boolean storeBusinessValidPeriod = "9".equals(storeDocument.getStoreBusinessValidPeriod());
        submitLicenseResponse.setLicenseType(Objects.requireNonNull(LicenseTypeEnum.matchName(storeDocument.getStoreBusinessType())).getCode());
        submitLicenseResponse.setLicenseLegalPerson(storeDocument.getStoreDirector());
        submitLicenseResponse.setIssueTime(DateUtil.parseDate(storeDocument.getStoreBusinessDate()));
        submitLicenseResponse.setLicenseAddress(storeDocument.getStoreBusinessAdd());
        submitLicenseResponse.setValidity(storeBusinessValidPeriod ? null : DateUtil.parse(storeDocument.getStoreBusinessValidPeriod(), "yyyy-MM-dd"));
        submitLicenseResponse.setValidityType(storeBusinessValidPeriod ? 0 : 1);
        submitLicenseResponse.setOperator(storeDocument.getStoreDirector());
        submitLicenseResponse.setFoodLicenseLegalPerson(storeDocument.getStoreFoodLicenseLegalRepresentative());
        submitLicenseResponse.setMainBusiness(storeDocument.getStoreFoodLicenseMainBusiness());
        submitLicenseResponse.setBusinessProject(storeDocument.getStoreFoodLicenseBusinessScope());
        submitLicenseResponse.setRemark(storeDocument.getStoreRemark());
        submitLicenseResponse.setLicenseUrl(storeDocument.getStoreBusinessImg());
        submitLicenseResponse.setLicenseName(storeDocument.getStoreBusinessName());
        submitLicenseResponse.setSocialCreditCode(storeDocument.getStoreBusinessNumber());
        submitLicenseResponse.setFoodLicenseUrl(storeDocument.getStoreFoodLicenseImg());
        submitLicenseResponse.setBusinessPremises(storeDocument.getStoreFoodLicenseBusinessAddress());
        submitLicenseResponse.setFoodLicenseCode(storeDocument.getStoreFoodLicense());
        submitLicenseResponse.setFoodLicenseStartTime(DateUtil.parseDate(storeDocument.getStoreFoodLicenseBeginDate()));
        submitLicenseResponse.setFoodLicenseEndTime(DateUtil.parseDate(storeDocument.getStoreFoodLicenseEndDate()));
        return submitLicenseResponse;
    }

    @Override
    public PageInfo<LicenseListResponse> licenseList(LicenseListRequest request, LoginUserInfo user) {
        //当前用户角色
        List<Long> userRoleIds = enterpriseUserRoleMapper.getUserRoleIds(user.getUserId());
        List<LicenseListResponse> licenseListResponses;
        //查证照列表数据
        if (userRoleIds.contains(UserRoleEnum.THEATER_MANAGER.getCode())) {
            //当前用户所属区域
            List<String> regionIds = userAuthMappingMapper.getMappingIdsByUserId(user.getUserId());
            if (CollectionUtils.isEmpty(regionIds)) {
                return new PageInfo<>();
            }
            List<RegionDO> fightRegion = regionDao.getFightRegionByRegionIds(regionIds);
            List<String> fightRegionIds = fightRegion.stream().map(RegionDO::getRegionId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(fightRegion)) {
                return new PageInfo<>();
            }
            PageHelper.startPage(request.getPageNum(), request.getPageSize());
            licenseListResponses = applyLicenseMapper.licenseList(request, null, fightRegionIds);
        } else {
            PageHelper.startPage(request.getPageNum(), request.getPageSize());
            licenseListResponses = applyLicenseMapper.licenseList(request, user.getUserId(), null);
        }
        List<String> userIdList = new ArrayList<>();
        for (LicenseListResponse vo : licenseListResponses) {
            userIdList.add(vo.getSupervisorUserId());
            userIdList.add(vo.getShopManagerUserId());
            userIdList.add(vo.getInvestmentManager());
        }
        if (CollectionUtils.isNotEmpty(userIdList)) {
            Map<String, String> userNameMap = userDAO.getUserNameMap(userIdList);
            for (LicenseListResponse vo : licenseListResponses) {
                vo.setSupervisorUserName(userNameMap.get(vo.getSupervisorUserId()));
                vo.setShopManagerUserName(userNameMap.get(vo.getShopManagerUserId()));
                vo.setInvestmentManagerName(userNameMap.get(vo.getInvestmentManager()));
                if (vo.getFightRegionId() != null) {
                    RegionDO regionDO = regionMapper.getBigRegionByRegionId(vo.getFightRegionId());
                    Long bigRegionIdByAreaId = regionDO.getId();
                    Map<Long, String> regionNameMap = regionDao.getRegionNameMap(Arrays.asList(bigRegionIdByAreaId, vo.getFightRegionId()));
                    vo.setBigRegionId(vo.getFightRegionId());
                    vo.setBigRegion(regionNameMap.get(vo.getFightRegionId()));
                }
            }
        }
        return new PageInfo<>(licenseListResponses);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean licenseExamine(Long shopId, Integer status, String result, LoginUserInfo user) {
        ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
        shopAuditInfoDO.setShopId(shopId);
        ShopSubStageStatusEnum shopSubStageStatusEnum = null;
        shopAuditInfoDO.setAuditType(AuditTypeEnum.LICENSE_APPROVAL.getCode());
        shopAuditInfoDO.setSubmittedUserId(user.getUserId());
        shopAuditInfoDO.setSubmittedUserName(user.getName());
        shopAuditInfoDO.setDataType(1);
        shopAuditInfoDO.setResultType(status);
        LicenseTransactDO licenseTransactDO = new LicenseTransactDO();
        licenseTransactDO.setShopId(shopId);
        if (Constants.ZERO_INTEGER.equals(status)) {
            //是否开业验收 改走的流程都已经完成 ->初始化开业验收数据
            preparationService.whetherToOpenForAcceptance(shopId);
            shopAuditInfoDO.setPassReason(result);
            shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_43;
            licenseTransactDO.setSubmitStatus(3);
        } else if (Constants.ONE_INTEGER.equals(status)) {
            licenseTransactDO.setSubmitStatus(2);
            shopAuditInfoDO.setRejectReason(result);
            shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_43;
            ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
            LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
        }
        applyLicenseMapper.updateByShopId(licenseTransactDO);
        //插入操作/意见
        shopAuditInfoMapper.insertSelective(shopAuditInfoDO);
        //更新阶段状态
        shopStageInfoDAO.updateShopStageAndAuditInfo(shopId, shopSubStageStatusEnum, shopAuditInfoDO.getId());
        return null;
    }
}
