package com.pj.api.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.pj.api.bo.InOutRecordBO;
import com.pj.api.bo.OtherBusinessBO;
import com.pj.api.wx.bo.MsgDataBO;
import com.pj.api.wx.service.WxService;
import com.pj.constants.UserTypeEnum;
import com.pj.current.config.MyConfig;
import com.pj.current.config.PartConfig;
import com.pj.current.config.WxConfig;
import com.pj.current.satoken.StpUserUtil;
import com.pj.project.relation_type_item.RelationTypeItem;
import com.pj.project.relation_type_item.RelationTypeItemService;
import com.pj.project.tb_account.TbAccount;
import com.pj.project.tb_account.TbAccountService;
import com.pj.project.tb_business.CarDisincle;
import com.pj.project.tb_business.TbBusiness;
import com.pj.project.tb_business.TbBusinessService;
import com.pj.project.tb_business_car.TbBusinessCar;
import com.pj.project.tb_business_car.TbBusinessCarService;
import com.pj.project.tb_business_item.TbBusinessItem;
import com.pj.project.tb_business_item.TbBusinessItemService;
import com.pj.project.tb_business_sort.TbBusinessSort;
import com.pj.project.tb_business_sort.TbBusinessSortService;
import com.pj.project.tb_car.TbCar;
import com.pj.project.tb_car.TbCarService;
import com.pj.project.tb_costomer.TbCostomer;
import com.pj.project.tb_costomer.TbCostomerService;
import com.pj.project.tb_declare.TbDeclare;
import com.pj.project.tb_declare.TbDeclareService;
import com.pj.project.tb_discount.TbDiscount;
import com.pj.project.tb_discount.TbDiscountService;
import com.pj.project.tb_disinfect.TbDisinfect;
import com.pj.project.tb_disinfect.TbDisinfectService;
import com.pj.project.tb_district.TbDistrict;
import com.pj.project.tb_district.TbDistrictService;
import com.pj.project.tb_goods.TbGoods;
import com.pj.project.tb_goods.TbGoodsService;
import com.pj.project.tb_item.TbItem;
import com.pj.project.tb_item_type.TbItemType;
import com.pj.project.tb_item_type.TbItemTypeService;
import com.pj.project.tb_pass_record.TbPassRecord;
import com.pj.project.tb_pass_record.TbPassRecordService;
import com.pj.project4sp.admin.SpAdmin;
import com.pj.project4sp.admin.SpAdminService;
import com.pj.project4sp.global.BusinessException;
import com.pj.utils.cache.RedisUtil;
import com.pj.utils.sg.AjaxJson;
import com.pj.utils.so.SoMap;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Or;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class ApiService {

    @Resource
    TbCostomerService tbCostomerService;
    @Resource
    @Lazy
    TbBusinessService tbBusinessService;
    @Resource
    TbPassRecordService tbPassRecordService;
    @Resource
    @Lazy
    TbBusinessCarService tbBusinessCarService;
    @Resource
    private TbDeclareService tbDeclareService;
    @Resource
    @Lazy
    private TbDisinfectService tbDisinfectService;
    @Resource
    private TbAccountService accountService;
    @Resource
    private TbDiscountService tbDiscountService;
    @Resource
    private TbBusinessItemService tbBusinessItemService;
    @Resource
    private SpAdminService spAdminService;
    @Resource
    private WxService wxService;
    @Resource
    private WxConfig wxConfig;
    @Resource
    private MyConfig myConfig;
    @Resource
    private TbCarService tbCarService;
    @Resource
    private RelationTypeItemService relationTypeItemService;

    @Resource
    private TbItemTypeService tbItemTypeService;

    @Resource
    private TbGoodsService tbGoodsService;

    @Resource
    private TbBusinessSortService tbBusinessSortService;

    private final List<String> CAR_LIST = StrUtil.splitTrim("浙,粤,京,津,冀,晋,蒙,辽,黑,沪,吉,苏,皖,赣,鲁,豫,鄂,湘,桂,琼,渝,川,贵,云,藏, 陕, 甘, 青, 宁", ",");


    public List<InOutRecordBO> getInOutRecord(SoMap so) {
        List<TbPassRecord> passRecords = tbPassRecordService.getList(so);
        List<InOutRecordBO> recordList = new ArrayList<>();
        for (TbPassRecord passRecord : passRecords) {
            InOutRecordBO record = new InOutRecordBO();
            BeanUtil.copyProperties(passRecord, record);
            TbCostomer costomer = tbCostomerService.getById(passRecord.getCustomerId());
            record.setCustomerContact(costomer.getPhone()).setDutyPeople(costomer.getDutyPeople());
            recordList.add(record);
        }
        return recordList;
    }

    public List<TbCostomer> getCustomerList(SoMap so) {
        List<TbCostomer> list = tbCostomerService.getList(so);
        return list;
    }

    public void confirmCustomer(Long customerId, String judgeContent) {
        TbCostomer costomer = tbCostomerService.getById(customerId);
        if (costomer != null && costomer.getJudgeStatus() == 1) {
            tbCostomerService.judge(customerId + "", 2, judgeContent);
        }
    }

    public List<TbBusinessCar> searchPartCar(String carNo) {
        if (StrUtil.isEmpty(carNo) || StrUtil.length(carNo) < 3) {
            return Collections.emptyList();
        }
        //查询出未缴费的车辆
        return tbBusinessCarService.searchForPayCar(carNo);
    }

    public void confirm(List<String> ids) {
        tbBusinessService.confirm(ids);
    }

    public Map<String, Object> getBusinessMoney(String carId, String state) {
        return tbBusinessService.getBusinessMoney(carId, state);
    }

    public Map<String, Object> getPartCarByChannel(String channel) {
        Map<String, Object> result = new HashMap<>();
        String carNo = RedisUtil.get(channel);
        if (StrUtil.isEmpty(carNo)) {
            return result;
        }
        TbBusinessCar tbBusinessCar = tbBusinessCarService.findTheLastRecord(carNo);
        if (tbBusinessCar == null) {
            return result;
        }
        Date now = new Date();
        Date startTime = tbBusinessCar.getRealInTime();
        if (tbBusinessCar.getPayTime() != null) {
            startTime = tbBusinessCar.getPayTime();
        }
        BigDecimal price = tbBusinessService.calculationPartMoney(startTime, now);
        Map<String, Object> car = new HashMap<>();
        car.put("id", tbBusinessCar.getId());
        car.put("carNo", tbBusinessCar.getCarNo());
        car.put("price", price);
        result.put("total", price);
        result.put("cars", Collections.singleton(car));
        return result;
    }

    public void addDeclare(TbDeclare tbDeclare) {
        if (StpUserUtil.isLogin() && !StrUtil.equals(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(), StpUserUtil.getCustomerId())) {
            String currentCustomerId = StpUserUtil.getCustomerId();
            tbDeclare.setCustomerId(currentCustomerId);
        }
        TbCostomer tbCostomer = tbCostomerService.getById(tbDeclare.getCustomerId());
        tbDeclare.setCustomerName(tbCostomer.getName());
        String chinaCarNo = tbDeclare.getChinaCarNo();
        if (StrUtil.isNotEmpty(chinaCarNo)) {
            chinaCarNo = chinaCarNo.toUpperCase();
            tbDeclare.setChinaCarNo(chinaCarNo);
        }
        String carNo = tbDeclare.getCarNo();
        if (StrUtil.isNotEmpty(carNo)) {
            carNo = carNo.toUpperCase();
            tbDeclare.setCarNo(carNo);
        }

        String nowStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        tbDeclare.setCreateTime(new Date()).setDeclareNo(nowStr + RandomUtil.randomNumbers(6));
        tbDeclareService.save(tbDeclare);
    }

    public void addDisinfect(TbDisinfect tbDisinfect) {
        if (StpUserUtil.isLogin() && !StrUtil.equals(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(), StpUserUtil.getCustomerId())) {
            String currentCustomerId = StpUserUtil.getCustomerId();
            tbDisinfect.setCustomerId(currentCustomerId);
        }
        TbCostomer tbCostomer = tbCostomerService.getById(tbDisinfect.getCustomerId());
        tbDisinfect.setCustomerName(tbCostomer.getName()).setApplyUnit(tbCostomer.getName());
        String nowStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        tbDisinfect.setCode(nowStr + RandomUtil.randomNumbers(6)).setApplyTime(DateUtil.now());
        tbDisinfectService.save(tbDisinfect);
    }

    public List<TbDeclare> getDeclareList(SoMap so) {
        return tbDeclareService.getList(so);
    }

    public TbAccount getAccountInfo(String customerId) {
        return accountService.getByCustomerId(customerId);
    }

    public List<TbDiscount> getDiscountInfo(SoMap so) {
        return tbDiscountService.getList(so);
    }

    public TbBusinessItem getBusinessItem(String id) {
        TbBusinessItem item = tbBusinessItemService.getById(id);
        TbBusiness business = tbBusinessService.getById(item.getBusinessId());
        item.setCardNo(business.getCardNo()).setChinaCarNo(business.getChinaCarNo()).setGoodsName(business.getGoodsName());
        return item;
    }

    public AjaxJson pickBusinessItem(String openid, long id) {
        TbBusinessItem tbBusinessItem = tbBusinessItemService.getById(id);
        if (tbBusinessItem == null) {
            return AjaxJson.getError("业务项目或已被删除");
        }
        SpAdmin spAdmin = spAdminService.findByOpenid(openid);
        if (spAdmin == null) {
            return AjaxJson.getError("用户已被删除或解绑");
        }
        if (tbBusinessItem.getPick() == 1) {
            return AjaxJson.getError("您慢了一步，其他用户已接单");
        }
        String customerId = spAdmin.getCustomerId();
        TbCostomer tbCostomer = tbCostomerService.getById(customerId);
        tbBusinessItem.setPick(1).setPickTime(new Date()).setPickCustomerId(tbCostomer.getId()).setPickCustomerName(tbCostomer.getName());
        tbBusinessItemService.updateById(tbBusinessItem);
        //todo 通知录入人员 已接单
        List<SpAdmin> spAdminList = spAdminService.findByCustomerId(UserTypeEnum.PLATFORM_ADMIN.getCustomerId());
        TbBusiness tbBusiness = tbBusinessService.getById(tbBusinessItem.getBusinessId());
        MsgDataBO msgDataBO = new MsgDataBO("订单号：" + tbBusinessItem.getNo(), tbCostomer.getName(), DateUtil.now(), tbBusiness.getGoodsName() + "(" + tbBusinessItem.getItemTypeName() + tbBusinessItem.getItemName() + ")");
        spAdminList.stream().filter(admin -> StrUtil.isNotEmpty(admin.getOpenid())).forEach(admin -> {
            String detailUrl = myConfig.getWebDomain() + "/pages/business-order/business-item?id=" + tbBusiness.getId() + "&itemId=" + tbBusinessItem.getId() + "&openid=" + openid;
            log.info("admin confirm business:[{}]", detailUrl);
            wxService.sendTemplateMsg(wxConfig.getBusinessPickTemplate(), admin.getOpenid(), msgDataBO, detailUrl);
        });
        return AjaxJson.getSuccess();
    }

    public void confirmBusinessItem(long id) {
        tbBusinessItemService.confirmBusinessItem(id);
    }

    public List<TbBusinessItem> getPartnerBusinessItem(SoMap startPage) {
        List<TbBusinessItem> list = tbBusinessItemService.getList(startPage);
        list.parallelStream().forEach(tbBusinessItem -> {
            TbBusiness tbBusiness = tbBusinessService.getById(tbBusinessItem.getBusinessId());
            List<TbBusinessCar> businessCars = tbBusinessCarService.findOtherBusinessCar(tbBusiness.getId());
            tbBusinessItem.setCardNo(businessCars.stream().map(TbBusinessCar::getCarNo).collect(Collectors.joining("、")));
        });
        return list;
    }

}
