package com.mmc.iuav.user.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.mmc.iuav.general.CodeUtil;
import com.mmc.iuav.http.BizException;
import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.constant.fdd.FddConstant;
import com.mmc.iuav.user.dao.CompanyAuthDao;
import com.mmc.iuav.user.dao.CompanyDao;
import com.mmc.iuav.user.dao.CooperationDao;
import com.mmc.iuav.user.entity.*;
import com.mmc.iuav.user.enums.RoleEnums;
import com.mmc.iuav.user.model.dto.LoginSuccessDTO;
import com.mmc.iuav.user.model.dto.WebsiteRangeDTO;
import com.mmc.iuav.user.model.qo.ApplyQO;
import com.mmc.iuav.user.model.vo.*;
import com.mmc.iuav.user.service.BackUserAccountService;
import com.mmc.iuav.user.service.CooperationService;
import com.mmc.iuav.user.service.UserAccountService;
import com.mmc.iuav.user.util.LocationUtils;
import com.mmc.iuav.user.util.SmsUtil;
import com.mmc.iuav.user.util.TDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zj @Date: 2023/5/17 21:19
 */
@Service
@Slf4j
public class CooperationServiceImpl implements CooperationService {
    @Autowired
    private CooperationDao cooperationDao;

    @Autowired
    private CompanyAuthDao companyAuthDao;

    @Autowired
    private BackUserAccountService backUserAccountService;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private CompanyDao companyDao;

    @Override
    public List<CooperationTagVO> listTag() {
        List<CooperationTagDO> list = cooperationDao.listTags();
        List<CooperationTagVO> resList =
                list.stream().map(CooperationTagDO::buildCooperationTagVO).collect(Collectors.toList());
        return resList;
    }

    @Override
    public ResultBody apply(UserApplyTagVO userApplyTagVO) {
        int applyCount = cooperationDao.countUserApplyTagByUid(userApplyTagVO.getUserAccountId());
        if (applyCount > 0) {
            return ResultBody.error(ResultEnum.TAG_APPLY_ALREADY_EXIST_ERROR);
        }
        int count = cooperationDao.userTagInfo(userApplyTagVO.getCooperationTagId(), userApplyTagVO.getUserAccountId());
        if (count > 0) {
            return ResultBody.error(ResultEnum.TAG_ALREADY_EXIST_ERROR);
        }
        // 判断企业认证
        CompanyInfoDO appCompanyInfoUId = companyDao.getAppCompanyInfoUId(userApplyTagVO.getUserAccountId());
        if (appCompanyInfoUId == null) {
            return ResultBody.error(ResultEnum.COMPANY_NOT_AUTH_ERROR);
        }
        if (appCompanyInfoUId.getLeader().equals(0)) {
            return ResultBody.error(ResultEnum.MEMBER_APPLY_ERROR);
        }
        Integer cooperationTagId = userApplyTagVO.getCooperationTagId();
        if (cooperationTagId == 1) {
            if ("".equals(userApplyTagVO.getBrandName()) || userApplyTagVO.getBrandName() == null) {
                return ResultBody.error(ResultEnum.THE_BRAND_NAME_CANNOT_BE_EMPTY);
            } else if ("".equals(userApplyTagVO.getBrandLogo()) || userApplyTagVO.getBrandLogo() == null) {
                return ResultBody.error(ResultEnum.THE_BRAND_LOGO_CANNOT_BE_EMPTY);
            }
        }
        UserApplyTagDO userApplyTagDO = new UserApplyTagDO(userApplyTagVO);
        //自定义订单 加盟订单编号设置规则：FN + 年份 + 8位随机数
        String orderNo = FddConstant.FN + TDateUtil.getCurrentYear() + CodeUtil.getRandomNum(8);
        userApplyTagDO.setOrderNo(orderNo);
        cooperationDao.addApply(userApplyTagDO);
        List<AttachmentVO> attachmentList = userApplyTagVO.getAttachmentList();
        if (!CollectionUtils.isEmpty(attachmentList)) {
            for (AttachmentVO attachmentVO : attachmentList) {
                TagApplyResourceDO tagApplyResourceDO =
                        new TagApplyResourceDO(attachmentVO, userApplyTagDO.getId());
                cooperationDao.addApplyResource(tagApplyResourceDO);
            }
        }
        // 修改单位的位置、品牌信息
        appCompanyInfoUId.setLon(userApplyTagVO.getLon());
        appCompanyInfoUId.setLat(userApplyTagVO.getLat());
        appCompanyInfoUId.setAddress(userApplyTagVO.getAddress());
        appCompanyInfoUId.setBrandLogo(userApplyTagVO.getBrandLogo());
        appCompanyInfoUId.setBrandName(userApplyTagVO.getBrandName());
        companyDao.updateCompanyInfo(appCompanyInfoUId);
        return ResultBody.success();
    }

    @Transactional
    @Override
    public ResultBody changeUserTag(UserCooperationTagVO userCooperationTagVO) {
        // 删除原来的
        cooperationDao.removeUserTag(userCooperationTagVO.getUserAccountId());
        // 添加新的
        if (!CollectionUtils.isEmpty(userCooperationTagVO.getCooperationTagIds())) {
            cooperationDao.batchInsertUserTag(userCooperationTagVO.getUserAccountId(), userCooperationTagVO.getCooperationTagIds());
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody getTagById(Integer id) {
        CooperationTagDO cooperationTagDO = cooperationDao.getTagById(id);
        if (cooperationTagDO == null) {
            return ResultBody.success();
        }
        return ResultBody.success(cooperationTagDO.buildCooperationTagVO());
    }

    @Override
    public PageResult listUserApplyTag(ApplyQO applyQO) {
        int count = cooperationDao.countListUserApplyTag(applyQO);
        if (count == 0) {
            return PageResult.buildPage(applyQO.getPageNo(), applyQO.getPageSize(), count);
        }
        int pageNo = applyQO.getPageNo();
        applyQO.buildCurrentPage();
        List<UserApplyTagDO> userApplyTagList = cooperationDao.listUserApplyTag(applyQO);
        List<UserApplyTagVO> list =
                userApplyTagList.stream()
                        .map(UserApplyTagDO::buildUserApplyTagVO)
                        .collect(Collectors.toList());
        return PageResult.buildPage(pageNo, applyQO.getPageSize(), count, list);
    }

    @Override
    public ResultBody getAuditSum() {
        AuditSumVO auditSumVO = new AuditSumVO();
        auditSumVO.setFailAuditSum(cooperationDao.getAuditSum(2));
        auditSumVO.setPassAuditSum(cooperationDao.getAuditSum(1));
        auditSumVO.setUnAuditedSum(cooperationDao.getAuditSum(0));
        return ResultBody.success(auditSumVO);
    }

    @Override
    public ResultBody deleteApplyTag(Integer id) {
        UserApplyTagDO userApplyTag = cooperationDao.getUserApplyTag(id);
        if (userApplyTag.getApplyStatus().equals(1)) {
            return ResultBody.error(ResultEnum.DELETE_PASS_ERROR);
        }
        cooperationDao.deleteApplyTag(id);
        return ResultBody.success();
    }

    @Override
    public ResultBody applyTagDetails(Integer id, Integer userAccountId) {
        // 初始化返回对象
        UserApplyTagDetailsVO userApplyTagDetailsVO = new UserApplyTagDetailsVO();
        // 获取企业认证信息
        CompanyInfoDO companyInfoDO = companyDao.getAppCompanyInfoUId(userAccountId);
        // 获取申请信息
        UserApplyTagDO userApplyTag = cooperationDao.getUserApplyTag(id);
        // 获取附件信息
        List<TagApplyResourceDO> tagApplyResourceList = cooperationDao.getUserApplyResource(id);
        if (CollectionUtils.isNotEmpty(tagApplyResourceList)) {
            List<AttachmentVO> list =
                    tagApplyResourceList.stream()
                            .map(TagApplyResourceDO::buildAttachmentVO)
                            .collect(Collectors.toList());
            userApplyTagDetailsVO.setAttachmentList(list);
        }
        userApplyTagDetailsVO.setCompanyName(companyInfoDO.getCompanyName());
        userApplyTagDetailsVO.setLicenseImg(companyInfoDO.getLicenseImg());
        userApplyTagDetailsVO.setCreditCode(companyInfoDO.getCreditCode());
        userApplyTagDetailsVO.setRemark(userApplyTag.getRemark());
        userApplyTagDetailsVO.setOrderNo(userApplyTag.getOrderNo());
        return ResultBody.success(userApplyTagDetailsVO);
    }

    @Transactional
    @Override
    public ResultBody approvalApplyTag(Integer id, Boolean status) {
        // 判断用户是否已经是该渠道
        UserApplyTagDO userApplyTag = cooperationDao.getUserApplyTag(id);
        int count =
                cooperationDao.userTagInfo(
                        userApplyTag.getCooperationTagId(), userApplyTag.getUserAccountId());
        UserAccountVO account = userAccountService.getUserAccountById(userApplyTag.getUserAccountId());
        if (status) {
            cooperationDao.updateApplyTagStatus(id, 1);
            if (count == 0) {
                // 审批通过往用户标签表中新增一条数据
                UserTagDO userTagDO = new UserTagDO();
                userTagDO.setUserAccountId(userApplyTag.getUserAccountId());
                userTagDO.setCooperationTagId(userApplyTag.getCooperationTagId());
                cooperationDao.insertUserTag(userTagDO);
            }
            // 审批通过生成后台对应的账号
            BUserAccountVO bUserAccountVO = this.generateBackUserAccountVO(userApplyTag);
            log.info("check apply cooperation tag, bUserAccountVO:{}", JSONObject.toJSONString(bUserAccountVO));
            ResultBody resultBody = backUserAccountService.insertBAccount(bUserAccountVO, null);
            if (!resultBody.getCode().equals(ResultEnum.SUCCESS.getResultCode())) {
                // 生成账号失败处理
                throw new BizException(ResultEnum.COOPERATION_CHECK_NOT_PASS_ERROR);
            }
            SmsUtil.sendPassCooperationApply(bUserAccountVO.getPhoneNum());
        } else {
            SmsUtil.sendNotPassCooperationApply(account.getPhoneNum());
            cooperationDao.updateApplyTagStatus(id, 2);
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody getTagIdByUserId(Integer userAccountId) {
        List<AppUserTagVO> tagIdByUserId = cooperationDao.getTagIdByUserId(userAccountId);
        return ResultBody.success(tagIdByUserId);
    }

    @Override
    public ResultBody getContractNoAndStatus(Integer tagId, Integer userAccountId) {
        UserApplyTagDO userApplyTagDO = cooperationDao.getContractNoAndStatus(tagId, userAccountId);
        return ResultBody.success(userApplyTagDO);
    }

    private BUserAccountVO generateBackUserAccountVO(UserApplyTagDO userApplyTagDO) {
        BUserAccountVO bUserAccountVO = new BUserAccountVO();
        UserAccountVO userAccountVO = userAccountService.getUserAccountById(userApplyTagDO.getUserAccountId());
        bUserAccountVO.setAccountNo(userAccountVO.getPhoneNum());
        bUserAccountVO.setUserName(userApplyTagDO.getApplyName());
        bUserAccountVO.setPhoneNum(userAccountVO.getPhoneNum());
        // String password = "YXF123456";
        bUserAccountVO.setPassWord(userAccountVO.getPhoneNum());
        bUserAccountVO.setAlertPwd(userAccountVO.getPhoneNum());
        bUserAccountVO.setAccountStatus(1);
        // 根据加盟类型分配角色
        if (userApplyTagDO.getCooperationTagId().equals(3)) {
            bUserAccountVO.setRoleId(RoleEnums.LEASE_FRANCHISEE.getId());
        } else if (userApplyTagDO.getCooperationTagId().equals(5)) {
            bUserAccountVO.setRoleId(RoleEnums.SERVICE_FRANCHISEE.getId());
        } else {
            bUserAccountVO.setRoleId(RoleEnums.FRANCHISEE.getId());
        }
        // 添加单位id
        CompanyInfoDO companyInfo = this.getCompanyInfo(userApplyTagDO);
        bUserAccountVO.setCompanyId(companyInfo.getId());
        bUserAccountVO.setRemark("加盟商自动生成");
        return bUserAccountVO;
    }

    private CompanyInfoDO getCompanyInfo(UserApplyTagDO userApplyTagDO) {
        // 查询小程序用户认证单位信息
        CompanyAuthDO companyAuth = companyAuthDao.getCompanyAuth(userApplyTagDO.getUserAccountId());
        // 验证是否已经添加单位信息
        CompanyInfoDO existCompanyInfo = companyDao.getCompanyInfoByName(companyAuth.getCompanyName());
        // 添加单位信息
        if (existCompanyInfo == null) {
            CompanyInfoDO companyInfoDO = new CompanyInfoDO();
            companyInfoDO.setCompanyType(1);
            companyInfoDO.setCompanyName(companyAuth.getCompanyName());
            companyInfoDO.setFullName(companyAuth.getCompanyName());
            companyInfoDO.setCompanyUserName(userApplyTagDO.getApplyName());
            companyInfoDO.setPhoneNum(userApplyTagDO.getApplyPhone());
            companyDao.addCompanyInfo(companyInfoDO);
            return companyInfoDO;
        } else {
            return existCompanyInfo;
        }
    }

    @Override
    public ResultBody editUserApplyTag(ApplyTagEditVO applyTagEditVO) {
        //判断当前服务商是否通过审核
        UserApplyTagDO userApplyTag = cooperationDao.getUserApplyTag(applyTagEditVO.getId());
        if (!userApplyTag.getApplyStatus().equals(1)) {
            return ResultBody.error("当前服务商暂未通过审核！");
        }

        //if (StringUtils.isBlank(applyTagEditVO.getRemark())) {
        UserApplyTagDO userApplyTagDO = new UserApplyTagDO();
        userApplyTagDO.setId(applyTagEditVO.getId());
        userApplyTagDO.setRemark(applyTagEditVO.getRemark());
        cooperationDao.updateUserApplyTag(userApplyTagDO);
        //  }
        cooperationDao.deleteApplyResource(applyTagEditVO.getId());
        if (!CollectionUtils.isEmpty(applyTagEditVO.getAttachmentList())) {
            applyTagEditVO.getAttachmentList().forEach(d -> d.setUserApplyTagId(userApplyTag.getId()));
            cooperationDao.insertApplyResource(applyTagEditVO.getAttachmentList());
        }
        // 修改单位网点位置信息
        CompanyInfoDO companyInfoDO = companyDao.getAppCompanyInfoUId(userApplyTag.getUserAccountId());
        CompanyInfoDO companyInfoDO1 = new CompanyInfoDO(applyTagEditVO);
        companyInfoDO1.setId(companyInfoDO.getId());
        companyInfoDO1.setBrandLogo(applyTagEditVO.getBrandLogo());
        companyDao.updateCompanyInfo(companyInfoDO1);
        return ResultBody.success();
    }

    @Override
    public ResultBody editUserApplyTagDetails(Integer id) {
        UserApplyTagDO userApplyTag = cooperationDao.getUserApplyTag(id);
        return ResultBody.success(userApplyTag == null ? null : userApplyTag.buildApplyTagEditVO());
    }

    @Override
    public PageResult listServiceBitmapData(Integer type, Integer pageNo, Integer pageSize, Double lon, Double lat) {
        int count = cooperationDao.countServiceBitmapData(type);
        if (count == 0) {
            return PageResult.buildPage(pageNo, pageSize, count);
        }
        List<WebsiteRangeDTO> list = cooperationDao.listServiceBitmapData(type, lon, lat, (pageNo - 1) * pageSize, pageSize)
                .stream().map(WebsiteInfoDO::buildWebsiteRangeDTO).collect(Collectors.toList());
        return PageResult.buildPage(pageNo, pageSize, count, list);
    }

    @Override
    public ResultBody appBrandList() {
        List<CompanyInfoDO> companyInfoDOS = cooperationDao.appBrandList();
        List<CompanyInfoVO> collect = companyInfoDOS.stream().map(CompanyInfoDO::buildCompanyInfoVO).collect(Collectors.toList());
        return ResultBody.success(collect);
    }

    @Override
    public ResultBody<UserApplyTagVO> appBrandMessage(Integer userAccountId) {
        UserApplyTagDO userApplyTagDO = cooperationDao.appBrandMessage(userAccountId);
        UserApplyTagVO userApplyTagVO = userApplyTagDO.buildUserApplyTagVO();
        return ResultBody.success(userApplyTagVO);
    }

    @Override
    public PageResult listCompanyInfoByCoopId(Integer coopId, Integer pageNo, Integer pageSize, Double lon, Double lat) {
        int count = cooperationDao.countListCompanyInfoByCoopId(coopId);
        if (count == 0) {
            return PageResult.buildPage(pageNo, pageSize, count);
        }
        List<CompanyInfoVO> list = cooperationDao.listCompanyInfoByCoopId(coopId, lon, lat, (pageNo - 1) * pageSize, pageSize)
                .stream().map(CompanyInfoDO::buildCompanyInfoVO).collect(Collectors.toList());
        // this.computerDistance(list, lon, lat);
        return PageResult.buildPage(pageNo, pageSize, count, list);
    }

    private List<CompanyInfoVO> computerDistance(List<CompanyInfoVO> companyInfoVOS, Double lon, Double lat) {
        for (CompanyInfoVO d : companyInfoVOS) {
            double distance = 0;
            if (d.getLon() != null && d.getLon() != 0 && d.getLat() != null && d.getLat() != 0) {
                distance = LocationUtils.getDistance(d.getLat(), d.getLon(), lat, lon);
            }
            d.setDistance(distance);
        }
        Collections.sort(companyInfoVOS, Comparator.comparing(CompanyInfoVO::getDistance));// 升序
        return companyInfoVOS;
    }
}
