package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import java.util.stream.Stream;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.module.jg.api.enums.CompanyTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.EquipSourceEnum;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgProjectContraptionService;
import com.yeejoin.amos.boot.module.ymt.api.dto.IdxBizJgProjectContraptionDto;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgProjectContraption;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgUseInfo;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgProjectContraptionMapper;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import javax.annotation.Resource;
import java.util.*;

/**
 * 管道工程装置表服务实现类
 *
 * @author system_generator
 * @date 2024-12-11
 */
@Service
public class IdxBizJgProjectContraptionServiceImpl extends BaseService<IdxBizJgProjectContraptionDto, IdxBizJgProjectContraption, IdxBizJgProjectContraptionMapper> implements IIdxBizJgProjectContraptionService {

    public static final String[] jsonFields = {"PRODUCT_PHOTO", "OTHER_ACCESSORIES", "PRODUCT_QUALIFICATION_CERTIFICATE", "START_LATITUDE_LONGITUDE",
            "END_LATITUDE_LONGITUDE"};
    public static final String IS_INTO_MANAGEMENT = "isIntoManagement";
    public static final String USE_REGISTRATION_CODE = "useRegistrationCode";
    public static final String REG_CODE_IS_NULL = "regCodeIsNull";
    public static final String PROJECT_CONTRAPTION = "projectContraption";
    public static final String EQU_CATEGORY = "equCategory";
    public static final String EQU_DEFINE = "equDefine";
    public static final String PROJECT_CONTRAPTION_NO = "projectContraptionNo";
    // 设备基本信息表单id
    private static final String EQUIP_INFO_FORM_ID = "equipInfo";
    @Resource
    private IdxBizJgUseInfoServiceImpl useInfoService;
    @Resource
    private IdxBizJgRegisterInfoServiceImpl registerInfoService;
    @Autowired
    private CommonServiceImpl commonServiceImpl;

    @Override
    public boolean saveOrUpdateData(IdxBizJgProjectContraption projectContraption) {
        return this.saveOrUpdate(projectContraption);
    }

    /**
     * 根据工程装置seq物理删除装置表数据和对应设备信息（数据库+es）
     *
     * @param sequenceNbr 工程装置表seq
     * @return result
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProjectAndEquInfoBySeq(Long sequenceNbr) {
        List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord).eq(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr).list();
        // 删除idx设备表信息 + 删除对应es数据
        List<String> records = useInfos.stream().map(IdxBizJgUseInfo::getRecord).collect(Collectors.toList());
        if (records.isEmpty()) return Boolean.TRUE;
        Map<String, Object> map = new HashMap<>();
        map.put("recordList", records);
        registerInfoService.batchDeleteByRecord(map);
        // 删除装置表信息
        this.removeById(sequenceNbr);
        return Boolean.TRUE;
    }

    /**
     * 根据入参 分页查询（当前）单位下的工程管道
     *
     * @param params      查询参数 Map
     * @param page        分页
     * @param reginParams 当前登录人信息
     * @return result
     */
    @Override
    public IPage<IdxBizJgProjectContraption> proConPageByParams(Map<String, String> params, Page<IdxBizJgProjectContraption> page, ReginParams reginParams) {
        CompanyBo company = reginParams.getCompany();
        String companyType = company.getCompanyType();
        String companyCode = company.getCompanyCode();
        // 是否是否纳管：true - 已纳管 false-未纳管
        boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
        // 使用登记编号
        String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
        // 使用登记编号是否为空 true/false
        String regCodeIsNull = params.get(REG_CODE_IS_NULL);
        // 工程装置名称
        String projectContraption = params.get(PROJECT_CONTRAPTION);
        // 工程装置编号
        String projectContraptionNo = params.get(PROJECT_CONTRAPTION_NO);
        // 设备类别code
        String equCategory = params.get(EQU_CATEGORY);
        // 设备类品种code
        String equDefine = params.get(EQU_DEFINE);
        IPage<IdxBizJgProjectContraption> pageList = lambdaQuery()
                .eq(CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                .eq(!ValidationUtil.isEmpty(equCategory), IdxBizJgProjectContraption::getEquCategory, equCategory)
                .eq(!ValidationUtil.isEmpty(equDefine), IdxBizJgProjectContraption::getEquDefine, equDefine)
                .like(!ValidationUtil.isEmpty(projectContraption), IdxBizJgProjectContraption::getProjectContraption, projectContraption)
                .like(!ValidationUtil.isEmpty(projectContraptionNo), IdxBizJgProjectContraption::getProjectContraptionNo, projectContraptionNo)
                .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .orderByDesc(IdxBizJgProjectContraption::getRecDate)
                .page(page);
        pageList.getRecords().forEach(record -> {
            record.setDataSourceName(EquipSourceEnum.getDataSourceName(record.getDataSource()));
            record.setFullAddress(
                    Stream.of(record.getProvinceName(), record.getCityName(), record.getCountyName(), record.getStreetName(), record.getAddress())
                            .map(value -> value == null ? "" : value)
                            .collect(Collectors.joining())
            );
            record.setCanEdit(this.checkContraptionIsCanEdit(record.getSequenceNbr()));
            record.setCanDelete(this.checkContraptionIsCanDelete(record.getSequenceNbr()));
        });
        return pageList;
    }

    private Boolean checkContraptionIsCanEdit(Long projectContraptionId) {
        Integer inUseTime = this.baseMapper.countContraptionInUseTimesForEdit(projectContraptionId);
        return inUseTime <= 0;
    }

    private Boolean checkContraptionIsCanDelete(Long projectContraptionId) {
        Integer inUseTime = this.baseMapper.countContraptionInUseTimesForDelete(projectContraptionId);
        return inUseTime <= 0;
    }

    @Override
    public List<IdxBizJgProjectContraption> proConListByParams(Map<String, String> params, ReginParams reginParams) {
        CompanyBo company = reginParams.getCompany();
        String companyType = company.getCompanyType();
        String companyCode = company.getCompanyCode();
        // 是否是否纳管：true - 已纳管 false-未纳管
        boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
        // 使用登记编号
        String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
        // 使用登记编号是否为空 true/false
        String regCodeIsNull = params.get(REG_CODE_IS_NULL);

        return lambdaQuery()
                .eq(CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .list();
    }

    /**
     * 分页查询
     */
    public Page<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionPage(Page<IdxBizJgProjectContraptionDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionList() {
        return this.queryForList("", false);
    }

    public Map<String, Map<String, Object>> details(String sequenceNbr) {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(sequenceNbr)) {
            resultMap.put(EQUIP_INFO_FORM_ID, Collections.emptyMap());
            return resultMap;
        }
        var baseMapper = this.getBaseMapper();
        Map<String, Object> projectContraptionMap = Optional.ofNullable(baseMapper.getDetail(sequenceNbr))
                .map(map -> {
                    commonServiceImpl.convertStringToJsonobject(map, jsonFields);
                    map.put("pipelineList", baseMapper.selectEquipList((String) map.get("SEQUENCE_NBR")));
                    return map;
                })
                .orElse(Collections.emptyMap());

        resultMap.put(EQUIP_INFO_FORM_ID, projectContraptionMap);
        return resultMap;
    }
}