package org.springblade.modules.app.manager;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wn.common.datamodel.ModelConvertUtil;
import com.wn.common.validator.Validator;
import org.springblade.modules.app.common.dto.ContractDTO;
import org.springblade.modules.app.common.dto.PictureInfoDTO;
import org.springblade.modules.app.common.dto.UserDTO;
import org.springblade.modules.app.common.enums.ApplicationTypeEnum;
import org.springblade.modules.app.common.enums.StateEnum;
import org.springblade.modules.app.common.enums.UserTypeEnum;
import org.springblade.modules.app.common.query.ContractQuery;
import org.springblade.modules.app.common.query.PictureQuery;
import org.springblade.modules.app.common.query.UserQuery;
import org.springblade.modules.app.common.vo.ApprovalVO;
import org.springblade.modules.app.common.vo.ContractVO;
import org.springblade.modules.app.constant.DbField;
import org.springblade.modules.app.constant.ErrorCode;
import org.springblade.modules.app.service.IContractService;
import org.springblade.modules.app.service.IPictureInfoService;
import org.springblade.modules.app.service.IAppUserService;
import org.springblade.modules.app.utils.ErrorMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author huyinuo
 */
@Slf4j
@Service
public class ContractManager {

    @Autowired
    private IContractService contractService;
    @Autowired
    private IAppUserService userService;
    @Autowired
    private IPictureInfoService pictureInfoService;
    @Autowired
    private UserManager userManager;

    public List<ContractVO> getContractList(Long id, Integer type){
        Validator.notNull(id, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(userService.getUserById(id), ErrorMsg.NEW("用户不存在"));
        Validator.isTrue(type == UserTypeEnum.SLAUGHTER.getCode() || type == UserTypeEnum.FARM.getCode(),
                ErrorMsg.NEW("用户类型有误"));

        ContractQuery query = new ContractQuery();
        if (type == UserTypeEnum.SLAUGHTER.getCode()) {
            query.setBuyerId(id);
        } else if (type == UserTypeEnum.FARM.getCode()) {
            query.setSalerId(id);
        }
        List<ContractDTO> contractList = contractService.getContractList(query);
//        log.info("返回数据为：{}", contractList);
        return ModelConvertUtil.copyListTo(contractList, ContractVO.class);
    }

    /**
     * 分页获取合同列表
     *
     * @param contractQuery
     * @return
     */
    public Page<ContractDTO> pageContract(ContractQuery contractQuery){
//        log.info("分页查询合同列表条件入参：{}", contractQuery);
        Validator.notNull(contractQuery, ErrorMsg.NEW("查询条件为空"));
        Page<ContractDTO> page = contractService.pageContract(contractQuery);
        List<ContractDTO> list = page.getRecords();
        if (CollectionUtils.isNotEmpty(list)){
            for (ContractDTO contractDTO : list) {
                PictureQuery pictureQuery = new PictureQuery();
                pictureQuery.setLinkId(contractDTO.getId());
                pictureQuery.setType(ApplicationTypeEnum.CONTRACT.getCode());
                contractDTO.setContractEnclosureUrl(pictureInfoService.getPictureInfo(pictureQuery).getUrl());
            }
        }
//        log.info("返回分页合同列表为：{}", JSONObject.toJSONString(page));
        return page;
    }

    public ContractVO addContract(ContractDTO contractDTO, UserDTO userDTO) {
//        log.info("添加合同入参：contractDTO：{}", contractDTO);
        Validator.notNull(contractDTO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(userDTO.getId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode()), ErrorMsg.NEW("创建合同的用户类型应该是屠宰场"));
        // 判断不可和同一个养殖场同时存在多条有效或待确认备案
        ContractQuery query = new ContractQuery();
        query.setBuyerId(userDTO.getId());
        List<ContractDTO> contractLists = contractService.getContractList(query);
        if (contractLists != null){
            for (ContractDTO contractDTO1 : contractLists) {
                if (contractDTO1.getSalerUserId().equals(contractDTO.getSalerUserId())){
                    boolean judge = contractDTO1.getState().equals(StateEnum.EFFECT.getCode()) || contractDTO1.getState().equals(StateEnum.INIT.getCode());
                    Validator.isTrue(!judge, ErrorMsg.NEW("不可同时存在多条有效备案"));
                }
            }
        }

        validatorInput(contractDTO);

        // 获取养殖场信息
        UserQuery userQuery = new UserQuery();
        userQuery.setName(contractDTO.getSalerUserName());
        UserDTO farmDTO = userManager.getFarmInfo(userQuery);
        String contractName = contractDTO.getBuyerUserName() + "&" + contractDTO.getSalerUserName() + "购销合同";

        ContractDTO updateContractDTO = new ContractDTO();
        updateContractDTO.setState(0);
        updateContractDTO.setCreatedTime(new Date());
        setContractInfo(contractDTO, userDTO, farmDTO, contractName, updateContractDTO);

        // 新增合同并获取id
        Long linkId = contractService.addContract(updateContractDTO);

        PictureInfoDTO updatePictureInfoDTO = new PictureInfoDTO();
        updatePictureInfoDTO.setLinkTable(DbField.TB_CONTRACT);
        updatePictureInfoDTO.setLinkId(linkId);
        updatePictureInfoDTO.setType(ApplicationTypeEnum.CONTRACT.getCode());
        updatePictureInfoDTO.setUrl(contractDTO.getContractEnclosureUrl());

        // 新增附件
        pictureInfoService.addPictureInfo(updatePictureInfoDTO);

        ContractVO contractVO = new ContractVO();
        contractVO.setContractID(linkId);
        return contractVO;
    }

    public ContractDTO getContractDetail(Long contractId, UserDTO userDTO) {
        Validator.notNull(contractId, ErrorCode.INPUT_PARAMETERS_NULL);

        ContractDTO contractDTO = contractService.getContractById(contractId);

        //检验当前查询用户与合同用户相符
        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())){
            Validator.isTrue(userDTO.getUserName().equals(contractDTO.getBuyerUserName()), ErrorMsg.NEW("合同屠宰场名称与实际不符"));
        }
        if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())){
            Validator.isTrue(userDTO.getUserName().equals(contractDTO.getSalerUserName()), ErrorMsg.NEW("合同养殖场名称与实际不符"));
        }

        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(contractId);

        PictureInfoDTO pictureInfoDTO = pictureInfoService.getPictureInfo(pictureQuery);

        contractDTO.setContractEnclosureUrl(pictureInfoDTO.getUrl());
//        log.info("请求结果为：{}", contractDTO);
        return contractDTO;
    }

    public ContractDTO getContractDetail(Long contractId) {
        Validator.notNull(contractId, ErrorCode.INPUT_PARAMETERS_NULL);

        ContractDTO contractDTO = contractService.getContractById(contractId);



        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(contractId);

        PictureInfoDTO pictureInfoDTO = pictureInfoService.getPictureInfo(pictureQuery);

        contractDTO.setContractEnclosureUrl(pictureInfoDTO.getUrl());
//        log.info("请求结果为：{}", contractDTO);
        return contractDTO;
    }

    public Boolean approvalContract(ApprovalVO approvalVO, UserDTO userDTO) {
        Validator.notNull(approvalVO, ErrorCode.INPUT_PARAMETERS_NULL);
        Integer type = userDTO.getType();
        Validator.isTrue(type.equals(UserTypeEnum.FARM.getCode()), ErrorMsg.NEW("审批合同的用户类型应该是养殖场"));
        Long linkId = approvalVO.getLinkId();
        Validator.notNull(linkId, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(approvalVO.getApprovalType().equals(ApplicationTypeEnum.CONTRACT.getCode()), ErrorMsg.NEW("审批类型为合同确认"));

        ContractDTO contractDTO = contractService.getContractById(linkId);
        Long buyerId = contractDTO.getBuyerUserId();

        Validator.notNull(contractDTO, ErrorMsg.NEW("合同不存在"));
        Validator.isTrue(contractDTO.getState().equals(0), ErrorMsg.NEW("合同状态不允许修改"));

        if (approvalVO.getResult().equals(0)){
            contractDTO.setState(-1);
        }
        if (approvalVO.getResult().equals(1)){
            // 判断不可同时存在多条有效备案
            ContractQuery contractQuery = new ContractQuery();
            contractQuery.setBuyerId(buyerId);
            contractQuery.setSalerId(userDTO.getId());
            List<ContractDTO> list = contractService.getContractList(contractQuery);
            if (list != null){
                for (ContractDTO contract : list) {
                    Validator.isTrue(!contract.getState().equals(StateEnum.EFFECT.getCode()), ErrorMsg.NEW("不可同时存在多条有效备案"));
                }
            }
            contractDTO.setState(1);
        }

        return contractService.updateContract(contractDTO);
    }

    public Boolean resubmit(ContractDTO contractDTO, UserDTO userDTO) {
        Validator.notNull(contractDTO, ErrorCode.INPUT_PARAMETERS_NULL);
        //判断入参非空
        validatorInput(contractDTO);
        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode()), ErrorMsg.NEW("修改合同信息的用户类型应该是屠宰场"));
        Long id = contractDTO.getId();
        ContractDTO updateContractDTO = contractService.getContractById(id);
        Validator.notNull(updateContractDTO, ErrorMsg.NEW("合同不存在"));

        UserQuery userQuery = new UserQuery();
        Validator.notNull(userService.getUserById(contractDTO.getSalerUserId()), ErrorMsg.NEW("对方养殖场不存在或已注销"));
        userQuery.setName(contractDTO.getSalerUserName());
        UserDTO farmDTO = userManager.getFarmInfo(userQuery);
        String contractName = contractDTO.getBuyerUserName() + "&" + contractDTO.getSalerUserName() + "购销合同";

        updateContractDTO.setState(0);
        setContractInfo(contractDTO, userDTO, farmDTO, contractName, updateContractDTO);

        contractService.updateContract(updateContractDTO);

        Long linkId = contractDTO.getId();
        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(linkId);
        PictureInfoDTO updatePictureInfoDTO = pictureInfoService.getPictureInfo(pictureQuery);
        Validator.isTrue(updatePictureInfoDTO.getLinkTable().equals(DbField.TB_CONTRACT), ErrorMsg.NEW("关联表出错"));
        Validator.isTrue(updatePictureInfoDTO.getType().equals(ApplicationTypeEnum.CONTRACT.getCode()), ErrorMsg.NEW("附件类型出错"));
        updatePictureInfoDTO.setUrl(contractDTO.getContractEnclosureUrl());

        pictureInfoService.updatePictureInfo(updatePictureInfoDTO);
        return true;
    }

    private void setContractInfo(ContractDTO contractDTO, UserDTO userDTO, UserDTO farmDTO, String contractName, ContractDTO updateContractDTO) {
        updateContractDTO.setBuyerUserId(userDTO.getId());
        updateContractDTO.setBuyerUserName(contractDTO.getBuyerUserName());
        updateContractDTO.setBuyerUserAddress(contractDTO.getBuyerUserAddress());
        updateContractDTO.setBuyerCreditCode(contractDTO.getBuyerCreditCode());
        updateContractDTO.setSalerUserId(farmDTO.getId());
        updateContractDTO.setSalerUserName(contractDTO.getSalerUserName());
        updateContractDTO.setSalerUserAddress(contractDTO.getSalerUserAddress());
        updateContractDTO.setSalerCreditCode(contractDTO.getSalerCreditCode());
        updateContractDTO.setContractExpiryTime(contractDTO.getContractExpiryTime());
        updateContractDTO.setNoEpidemicProofUrl(contractDTO.getNoEpidemicProofUrl());
        updateContractDTO.setContractName(contractName);
    }

    private void validatorInput(ContractDTO contractDTO) {
        Validator.notBlank(contractDTO.getBuyerUserName(), ErrorMsg.NEW("屠宰场名称为空"));
        Validator.notBlank(contractDTO.getBuyerUserAddress(), ErrorMsg.NEW("屠宰场地址为空"));
        Validator.notNull(contractDTO.getBuyerCreditCode(), ErrorMsg.NEW("屠宰场社会统一信用码为空"));
        Validator.notBlank(contractDTO.getSalerUserName(), ErrorMsg.NEW("养殖场名称为空"));
        Validator.notBlank(contractDTO.getSalerUserAddress(), ErrorMsg.NEW("养殖场地址为空"));
        Validator.notNull(contractDTO.getSalerCreditCode(), ErrorMsg.NEW("养殖场社会统一信用代码为空"));
        Validator.notBlank(contractDTO.getContractExpiryTime(), ErrorMsg.NEW("合同到期时间为空"));
        Validator.notNull(contractDTO.getNoEpidemicProofUrl(), ErrorMsg.NEW("三年无疫情证明为空"));
        Validator.notNull(contractDTO.getContractEnclosureUrl(), ErrorMsg.NEW("合同附件为空"));
    }
}
