package com.bohuikeji.delivery.backstage.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bohuikeji.delivery.backstage.entity.TConfig;
import com.bohuikeji.delivery.backstage.entity.TCustomer;
import com.bohuikeji.delivery.backstage.entity.TCustomerTemplate;
import com.bohuikeji.delivery.backstage.entity.TMerchantConfig;
import com.bohuikeji.delivery.backstage.mapper.TConfigMapper;
import com.bohuikeji.delivery.backstage.service.ITConfigService;
import com.bohuikeji.delivery.backstage.service.ITCustomerService;
import com.bohuikeji.delivery.backstage.service.ITCustomerTemplateService;
import com.bohuikeji.delivery.backstage.service.ITMerchantConfigService;
import com.bohuikeji.frame.module.admin.base.ServiceImplBase;
import com.bohuikeji.frame.module.admin.entity.TFranchiseeInformation;
import com.bohuikeji.frame.module.admin.service.ITFranchiseeInformationService;
import com.bohuikeji.frame.module.admin.entity.sys.SysConfig;
import com.bohuikeji.frame.module.admin.utils.MapUtils;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class TConfigServiceImpl  extends ServiceImplBase<TConfigMapper, TConfig> implements ITConfigService {
    final ITFranchiseeInformationService franService;
    final ITCustomerService customerService;
    final ITCustomerTemplateService templateService;
    final ITMerchantConfigService merchantConfigService;

    @Override
    public TConfig getConfigByKey(String key,Integer franId) {
        return getOne(new QueryWrapper<TConfig>().eq("config_key",key),false);
    }

    @Override
    public TConfig getConfigByMark(Integer configId, Integer franId) {
        return getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",franId),false);
    }

    @Override
    public List<TConfig> getListByGroup(String groupKey,Integer franId) {
        return list(new QueryWrapper<TConfig>().eq("fran_id",franId).eq("config_group",groupKey));
    }

    @Override
    public SysConfig getSysConfigByKey(String key,String location) {
        TConfig config=getOne(
                new QueryWrapper<TConfig>()
                        .eq("config_key",key)
                        .eq("fran_id",franService.checkPio(MapUtils.getAddressReGeo(location)).getFranId()),false);
        return config.toOldConfig();
    }

    @Override
    public TConfig getByIdWithCustomer(Integer configId, Integer customerId,Integer franId) {
        TConfig config=new TConfig();
        TCustomer customer=customerService.getById(customerId);
        TFranchiseeInformation franchiseeInformation = franService.getOne(new QueryWrapper<TFranchiseeInformation>().eq("fran_id",franId));
        if (customer==null){
            if(getIsNotTrue(configId)){
                return getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",franchiseeInformation.getFranId()));
            }
            return getOne(new QueryWrapper<TConfig>().eq("id",configId).eq("fran_id",1));
        }
        if(franchiseeInformation == null){
            franchiseeInformation = franService.getOne(new QueryWrapper<TFranchiseeInformation>().eq("fran_id",1));
        }
        if(StringUtils.isNotBlank(customer.getTemplateId())){
            if(getIsNotTrue(configId)){
                return getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",franchiseeInformation.getFranId()));
            }
            config = getTConfigs(configId,franchiseeInformation,customer);
            if(config != null){
                return config;
            }
        }
        if("商家用户".equals(customer.getCustomerType())){
            config = getBConfigs(configId,franchiseeInformation);
            if(config != null){
                return config;
            }
        }
        if("普通客户".equals(customer.getCustomerType())){
            if(getIsNotTrue(configId)){
                config = getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",franchiseeInformation.getFranId()));
            }else {
                config = getOne(new QueryWrapper<TConfig>().eq("id",configId).eq("fran_id",franchiseeInformation.getFranId()));
            }
            if(config != null){
                return config;
            }
        }
        if(getIsNotTrue(configId)){
            return getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",1));
        }
        return getOne(new QueryWrapper<TConfig>().eq("id",configId).eq("fran_id",franchiseeInformation.getFranId()));
    }

    /**
     * 商家B端计费
     * 下单时
     * @param configId
     * @param information
     * @return
     */
    private TConfig getBConfigs(Integer configId,TFranchiseeInformation information) {
        TConfig config=new TConfig();
        TMerchantConfig merchantConfig;
        if(getIsNotTrue(configId)){
            merchantConfig = merchantConfigService.getOne(new QueryWrapper<TMerchantConfig>().eq("config_mark",getMark(configId)).eq("fran_id",information.getFranId()));
        }else {
            merchantConfig = merchantConfigService.getOne(new QueryWrapper<TMerchantConfig>().eq("id",configId).eq("fran_id",information.getFranId()));
        }
        if(merchantConfig != null){
            config.setConfigValue(merchantConfig.getConfigValue());
            config.setId(merchantConfig.getId());
            config.setConfigKey(merchantConfig.getConfigKey());
            config.setConfigName(merchantConfig.getConfigName());
            config.setConfigGroup(merchantConfig.getConfigGroup());
            config.setFranId(merchantConfig.getFranId());
        }else {
            if(getIsNotTrue(configId)){
                config = getOne(new QueryWrapper<TConfig>().eq("config_mark",getMark(configId)).eq("fran_id",1));
            }else {
                config = getOne(new QueryWrapper<TConfig>().eq("id",configId).eq("fran_id",information.getFranId()));
            }
        }
        return config;
    }

    /**
     * 客户模板计费
     * 下单时
     * @param configId
     * @param information
     * @return
     */
    private TConfig getTConfigs(Integer configId,TFranchiseeInformation information,TCustomer customer) {
        TConfig config=new TConfig();
        TCustomerTemplate configTemplate=templateService.getOne(new QueryWrapper<TCustomerTemplate>().eq("fran_id",information.getFranId()).eq("template_id",configId));
        if(configTemplate != null){
            config.setConfigValue(configTemplate.getConfigValue());
            config.setId(configTemplate.getTemplateId());
            config.setConfigKey(configTemplate.getConfigKey());
            config.setConfigName(configTemplate.getConfigName());
            config.setConfigGroup(configTemplate.getConfigGroup());
            config.setFranId(configTemplate.getFranId());
        }else {
            if("商家用户".equals(customer.getCustomerType())){
                config = getBConfigs(configId,information);
            }else {
                config = getOne(new QueryWrapper<TConfig>().eq("id",configId).eq("fran_id",information.getFranId()));
            }
        }
        return config;
    }

    @Override
    public List<TConfig> getFranConfigByGroupWithCustomer(String groupKey,String location,Integer customerId) {
        List<TConfig> configs=new ArrayList<>();
        TCustomer customer=customerService.getById(customerId);
        TFranchiseeInformation fran=franService.checkPio(MapUtils.getAddressReGeo(location));
        //log.info("计费模板对应的加盟商信息:[{}]",fran.getFranName());
        if(fran == null){
            fran = franService.getById(1);
        }
        //log.info("计费模板对应的商户信息:[{}]",customer);
        if (customer==null){
            return getFranIdConfigs(groupKey,fran);//加盟商C端计费
        }
        //如果客户绑定可模板，优先使用模板计费
        if(StringUtils.isNotBlank(customer.getTemplateId())){//用户绑定模板计费
            configs = getTemplateConfigs(groupKey,customer,fran.getFranId());
            if(configs.size()>0){
                return configs;
            }
        }
        if("商家用户".equals(customer.getCustomerType())){
            configs = getMerchantConfigs(groupKey,fran);
            if(configs.size()>0){
                return configs;
            }
        }
        if("普通客户".equals(customer.getCustomerType())){
            configs = getFranIdConfigs(groupKey,fran);
            if(configs.size()>0){
                return configs;
            }
        }
        //没有模板走加盟商计费
        //log.error("客户是普通类型的走的是加盟商C端模板计费2:商户类型：{},配置类型：{}",customer.getCustomerType(),groupKey);
        return configs;

    }

    /**
     * 客户C端计费
     * @param groupKey
     * @param id
     * @return
     */
    private List<TConfig> getFranIdConfigs(String groupKey, TFranchiseeInformation fran) {
        List<TConfig> configs=list(new QueryWrapper<TConfig>()
                .eq("config_group",groupKey)
                .eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
        if (configs==null||configs.size()<1){
            for (int i = 0; i < 5; i++) {
                fran=franService.getSuper(fran.getFranId());
                if (fran==null){
                    //log.error("【上级加盟商获取异常】参数：key={}，location={}",groupKey,location);
                    configs=list(new QueryWrapper<TConfig>().eq("config_group",groupKey).eq("fran_id",1).eq("show_type",1).orderByDesc("config_sort"));
                } else{
                    configs=list(new QueryWrapper<TConfig>().eq("config_group",groupKey).eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
                }
                if (configs!=null&&configs.size()>1){
                    break;
                }
            }
        }
        return configs;
    }

    /**
     * 商家C端计费
     * 初始配置
     * @param groupKey
     * @param id
     * @return
     */
    private List<TConfig> getMerchantConfigs(String groupKey, TFranchiseeInformation fran) {
        List<TConfig> configs = new ArrayList<>();
        List<TMerchantConfig> merchantConfigs=merchantConfigService.list(new QueryWrapper<TMerchantConfig>()
                .eq("config_group",groupKey)
                .eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
        if (merchantConfigs!=null||merchantConfigs.size()>1){
            merchantConfigs.forEach(t->{
                TConfig config=new TConfig();
                config.setConfigGroup(t.getConfigGroup());
                config.setConfigKey(t.getConfigKey());
                config.setConfigName(t.getConfigName());
                config.setConfigValue(t.getConfigValue());
                config.setId(t.getId());
                configs.add(config);
            });
        }
        return configs;
    }

    /**
     * 客户模板计费
     * 初始配置
     * 初始配置
     * @param groupKey
     * @param id
     * @return
     */
    private List<TConfig> getTemplateConfigs(String groupKey,TCustomer customer,Integer id) {
        List<TConfig> configs=new ArrayList<>();
        TCustomerTemplate template=templateService.getOne(new QueryWrapper<TCustomerTemplate>().eq("template_id",customer.getTemplateId()).eq("fran_id",id));
        if (template!=null){
            List<TCustomerTemplate> templates=templateService.getListByGroup(groupKey,template.getFranId(),template.getTemplateCode());
            templates.forEach(t->{
                TConfig config=new TConfig();
                config.setConfigGroup(t.getConfigGroup());
                config.setConfigKey(t.getConfigKey());
                config.setConfigName(t.getConfigName());
                config.setConfigValue(t.getConfigValue());
                config.setId(t.getTemplateId());
                configs.add(config);
            });
        }
        return configs;
    }

    private List<TConfig> getFranConfigs(String groupKey, String location) {
        TFranchiseeInformation fran=franService.checkPio(MapUtils.getAddressReGeo(location));
        List<TConfig> configs=list(new QueryWrapper<TConfig>()
                .eq("config_group",groupKey)
                .eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
        if (configs==null||configs.size()<1){
            for (int i = 0; i < 5; i++) {
                fran=franService.getSuper(fran.getFranId());
                if (fran==null){
                    log.error("【上级加盟商获取异常】参数：key={}，location={}",groupKey,location);
                    configs=list(new QueryWrapper<TConfig>().eq("config_group",groupKey).eq("fran_id",1).eq("show_type",1).orderByDesc("config_sort"));
                }
                else{
                    configs=list(new QueryWrapper<TConfig>().eq("config_group",groupKey).eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
                }
                if (configs!=null&&configs.size()>1){
                    break;
                }
            }
        }
        return configs;
    }

    /*@Override
    public List<TConfig> getFranConfigByGroupCustomer(String groupKey,Integer franId,Integer customerId) {
        TCustomer customer=customerService.getById(customerId);
        List<TConfig> configs=list( new QueryWrapper<TConfig>()
                .eq("config_group",groupKey)
                .eq("fran_id",franId).orderByDesc("config_sort"));

        if(StringUtils.isBlank(customer.getTemplateId())){
            return configs;
        }
        TCustomerTemplate template=templateService.getById(customer.getTemplateId());
        if (template==null){
            return configs;
        }
        List<TCustomerTemplate> templates=templateService.getListByGroup(groupKey,template.getFranId(),template.getTemplateCode());
        configs.clear();
        templates.forEach(t->{
            TConfig config=new TConfig();
            config.setConfigGroup(t.getConfigGroup());
            config.setConfigKey(t.getConfigKey());
            config.setConfigName(t.getConfigName());
            config.setConfigValue(t.getConfigValue());
            config.setId(t.getTemplateId());
            configs.add(config);
        });
        return configs;

    }*/

    /**
     * 获取加盟计费规则组的默认规则
     * 【注意】如未配置默认规则，则使用顺序第一条作为默认
     * 【场景】目前开放平台使用本系统下单功能，由于各个第三方系统业务逻辑及对接程度存在差异，暂时不提供选择计费项目功能，即只提供一种当地默认计费规则
     * 【其他】对于定制计费的合作平台请使用客户模板方式绑定计费规则，未绑定按地区默认规则计费
     *
     * @param groupKey 计费配置组KEY
     * @param location 地区经纬度，通常是下单地址坐标
     * @return
     */
    @Override
    public  List<TConfig> getFranConfigByGroup(String groupKey, String location) {
        //没有模板走加盟商计费
        return getFranConfigs(groupKey, location);
    }

    @Override
    public TConfig getOpenConfigByGroup(String confiogName, String groupKey, String location,Integer customerId) {
        TCustomer customer = customerService.getById(customerId);
        TFranchiseeInformation fran=franService.checkPio(MapUtils.getAddressReGeo(location));
        TConfig config=getOne(new QueryWrapper<TConfig>().eq("config_name",confiogName).eq("config_group",groupKey).eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
        if("商家用户".equals(customer.getCustomerType())){
            TMerchantConfig merchantConfig = merchantConfigService.getOne(new QueryWrapper<TMerchantConfig>().eq("config_name",confiogName).eq("config_group",groupKey).eq("fran_id",fran.getFranId()).eq("show_type",1).orderByDesc("config_sort"));
            if(merchantConfig!=null){
                config=new TConfig();
                config.setConfigGroup(merchantConfig.getConfigGroup());
                config.setConfigKey(merchantConfig.getConfigKey());
                config.setConfigName(merchantConfig.getConfigName());
                config.setConfigValue(merchantConfig.getConfigValue());
                config.setId(merchantConfig.getId());
            }
        }else {
            if (config==null){
                config=getOne(new QueryWrapper<TConfig>().eq("config_name",confiogName).eq("config_group",groupKey).eq("fran_id",1).eq("show_type",1).orderByDesc("config_sort"));
            }
        }
        return config;
    }

    /**
     * 获取大客户附加计费组配置
     *
     * @param customerId 客户ID
     * @return
     */
    @Override
    public List<TCustomerTemplate> getBigCustomerAddList(Integer customerId) {
        TCustomer customer=customerService.getById(customerId);
        //log.info("计费模板对应的商户信息:[{}]",customer);
        if (customer==null){
            return null;
        }
        //未绑定计费模板，返回null
        if(StringUtils.isBlank(customer.getTemplateId())){
            return null;
        }
        TCustomerTemplate firstTemp= templateService.getById(customer.getTemplateId());
        if(firstTemp==null){
            return null;
        }
        List<TCustomerTemplate> list=templateService.getListByGroup("order_price_add",firstTemp.getFranId(),firstTemp.getTemplateCode());
        List<TCustomerTemplate> rsList=new ArrayList<>(list.size());
        for (TCustomerTemplate template : list) {
            if (template.getConfigValue().getFloat("费用")>0){
                rsList.add(template);
            }
        }
        return rsList;
    }

    @Override
    public JSONObject getPremiumJson(Integer franId, String configGroup, Integer customerId) {
        JSONObject allJson = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        TCustomer customer=customerService.getById(customerId);
        if (customer==null){
            return null;
        }
        BigDecimal total = BigDecimal.ZERO;
        //未绑定直接返回计费
        if(StringUtils.isNotBlank(customer.getTemplateId())){
            log.info("溢价计费1：用户手机号：{},用户类型：{},加盟商Id:{}",customer.getCustomerPhone(),customer.getCustomerType(),franId);
            TCustomerTemplate template=templateService.getById(customer.getTemplateId());
            if(template != null){
                log.info("客户已绑定模板时的溢价计费：用户手机号：{},用户类型：{}",customer.getCustomerId(),customer.getCustomerType());
                List<TCustomerTemplate> templates=templateService.getPremiumListByGroup(configGroup,template.getFranId(),template.getTemplateCode());
                allJson = getTJson(total,jsonArray,templates);
            }else {
                if("商家用户".equals(customer.getCustomerType())){
                    log.info("模板为空时商户溢价计费1：用户手机号：{},用户类型：{}",customer.getCustomerId(),customer.getCustomerType());
                    List<TMerchantConfig> merchantConfigs=merchantConfigService.getBListByGroup(configGroup,franId);
                    allJson = getBJson(total,jsonArray,merchantConfigs);
                }
                if("普通客户".equals(customer.getCustomerType())){
                    log.info("模板为空时个人溢价计费1：用户手机号：{},用户类型：{}",customer.getCustomerId(),customer.getCustomerType());
                    List<TConfig> configs=list(new QueryWrapper<TConfig>().eq("config_status","使用中").eq("config_group",configGroup).eq("fran_id",franId).eq("show_type",1).orderByDesc("config_sort"));
                    allJson = getCJson(total,jsonArray,configs);
                }
            }
        }else {
            if("商家用户".equals(customer.getCustomerType())){
                log.info("模板为空时商户溢价计费2：用户手机号：{},用户类型：{}",customer.getCustomerId(),customer.getCustomerType());
                List<TMerchantConfig> merchantConfigs=merchantConfigService.getBListByGroup(configGroup,franId);
                allJson = getBJson(total,jsonArray,merchantConfigs);
            }
            if("普通客户".equals(customer.getCustomerType())){
                log.info("模板为空时个人溢价计费2：用户手机号：{},用户类型：{}",customer.getCustomerId(),customer.getCustomerType());
                List<TConfig> configs=list(new QueryWrapper<TConfig>().eq("config_status","使用中").eq("config_group",configGroup).eq("fran_id",franId).eq("show_type",1).orderByDesc("config_sort"));
                allJson = getCJson(total,jsonArray,configs);
            }
        }
        return allJson;
    }

    /**
     * 加盟商B端溢价
     * @param total
     * @param jsonArray
     * @param merchantConfigs
     * @return
     */
    private JSONObject getBJson(BigDecimal total,JSONArray jsonArray,List<TMerchantConfig> merchantConfigs){
        JSONObject allJson = new JSONObject();
        JSONObject jsonObject;
        if(merchantConfigs.size()>0){
            for (TMerchantConfig t : merchantConfigs) {
                jsonObject = new JSONObject();
                if(getIsTure(t.getConfigValue())){
                    jsonObject.put("key", t.getConfigName()+"：");
                    jsonObject.put("value", t.getConfigValue().getString("溢价费用"));
                    total = total.add(new BigDecimal(t.getConfigValue().getString("溢价费用")));
                    jsonArray.add(jsonObject);
                }
            }
        }
        allJson.put("总溢价",total);
        allJson.put("detailed",jsonArray);
        return allJson;
    }
    /**
     * 加盟商C端溢价
     * @param total
     * @param configs
     * @param jsonArray
     * @return
     */
    private JSONObject getCJson(BigDecimal total,JSONArray jsonArray,List<TConfig> configs){
        JSONObject allJson = new JSONObject();
        JSONObject jsonObject;
        if(configs.size()>0){
            for (TConfig t : configs) {
                jsonObject = new JSONObject();
                if(getIsTure(t.getConfigValue())){
                    jsonObject.put("key", t.getConfigName()+"：");
                    jsonObject.put("value", t.getConfigValue().getString("溢价费用"));
                    total = total.add(new BigDecimal(t.getConfigValue().getString("溢价费用")));
                    jsonArray.add(jsonObject);
                }
            }
        }
        allJson.put("总溢价",total);
        allJson.put("detailed",jsonArray);
        return allJson;
    }
    /**
     * 客户模板溢价
     * @param total
     * @param templates
     * @param jsonArray
     * @return
     */
    private JSONObject getTJson(BigDecimal total,JSONArray jsonArray,List<TCustomerTemplate> templates){
        JSONObject allJson = new JSONObject();
        JSONObject jsonObject;
        if(templates.size()>0){
            for (TCustomerTemplate t : templates) {
                jsonObject = new JSONObject();
                if(getIsTure(t.getConfigValue())){
                    jsonObject.put("key", t.getConfigName()+"：");
                    jsonObject.put("value", t.getConfigValue().getString("溢价费用"));
                    total = total.add(new BigDecimal(t.getConfigValue().getString("溢价费用")));
                    jsonArray.add(jsonObject);
                }
            }
        }
        allJson.put("总溢价",total);
        allJson.put("detailed",jsonArray);
        return allJson;
    }

    private boolean getIsTure(JSONObject configValue){
        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now();
        if(date.isEqual(LocalDate.parse(configValue.getString("开始日期"))) || date.isEqual(LocalDate.parse(configValue.getString("结束日期")))){
            if (time.isAfter(LocalTime.parse(configValue.getString("开始时间"))) && time.isBefore(LocalTime.parse(configValue.getString("结束时间")))) {
                return true;
            }
        }
        if (date.isAfter(LocalDate.parse(configValue.getString("开始日期"))) && date.isBefore(LocalDate.parse(configValue.getString("结束日期")))) {
            if (time.isAfter(LocalTime.parse(configValue.getString("开始时间"))) && time.isBefore(LocalTime.parse(configValue.getString("结束时间")))) {
                return true;
            }
        }
        return false;
    }

    private boolean getIsNotTrue(Integer config){
       String carType;
       if(config==61){
           return true;
       }
       if(config==62){
           return true;
       }
       if(config==63){
           return true;
       }
        return false;
    }

    private String getMark(Integer config){
        String carType="ddc";
        if(config==61){
            carType = "van";
        }
        if(config==62){
            carType = "car";
        }
        if(config==63){
            carType = "truck";
        }
        return carType;
    }

}