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.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.pj.api.bo.InOutRecordBO;
import com.pj.api.wx.bo.MsgDataBO;
import com.pj.api.wx.service.WxService;
import com.pj.current.config.MyConfig;
import com.pj.current.config.WxConfig;
import com.pj.current.satoken.StpUserUtil;
import com.pj.project.tb_account.TbAccount;
import com.pj.project.tb_account.TbAccountService;
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_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_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.utils.cache.RedisUtil;
import com.pj.utils.sg.AjaxJson;
import com.pj.utils.so.SoMap;
import lombok.extern.slf4j.Slf4j;
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.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 *
 */

@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;

    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) {
        return tbBusinessCarService.searchPartCar(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);
        TbBusinessCar tbBusinessCar = tbBusinessCarService.findInBuNoOutAndNotPay(carNo);
        if (tbBusinessCar == null) {
            return result;
        }
        Date now = new Date();
        BigDecimal price = tbBusinessService.calculationPartMoney(tbBusinessCar.getRealInTime(), now);
        BigDecimal dif = price.subtract(tbBusinessCar.getMoney());
        Map<String, Object> car = new HashMap<>();
        car.put("id", tbBusinessCar.getId());
        car.put("carNo", tbBusinessCar.getCarNo());
        car.put("price", dif);
        result.put("total", dif);
        result.put("cars", Collections.singleton(car));
        return result;
    }

    public void addDeclare(TbDeclare tbDeclare) {
        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);
        }
//        SpAdmin admin=StpUserUtil.getAdmin();
//        if (admin!=null) {
//            tbDeclare.setCustomerId(admin.getCustomerId());
//        }
        String productionCode = tbDeclare.getProductionCode();
        Date now = new Date();
        if (StrUtil.isNotEmpty(productionCode)) {
            TbDeclare db = tbDeclareService.findByProductionCode(productionCode);
            if (db != null) {
                BeanUtil.copyProperties(tbDeclare, db, "id");
                db.setCreateTime(now);
                tbDeclareService.updateById(db);
                return;
            }
        }
        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) {
        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) {
        return tbBusinessItemService.getById(id);
    }

    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("用户已被删除或解绑");
        }
        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 通知录入人员 已接单
        String businessId = tbBusinessItem.getBusinessId();
        TbBusiness tbBusiness = tbBusinessService.getById(businessId);
        String businessCustomerId = tbBusiness.getCustomerId();
        List<SpAdmin> spAdminList = spAdminService.findByCustomerId(businessCustomerId);
        MsgDataBO msgDataBO=new MsgDataBO("您有一条新的接单通知",tbCostomer.getName(), DateUtil.now(),tbBusinessItem.getItemTypeName()+"（"+tbBusinessItem.getItemName()+"）");
        spAdminList.stream().filter(admin -> StrUtil.isNotEmpty(admin.getOpenid())).forEach(admin -> {
            String detailUrl = myConfig.getWebDomain() + "/pages/business-order/business-item?id=" + tbBusinessItem.getId();
            wxService.sendTemplateMsg(wxConfig.getBusinessPickTemplate(),admin.getOpenid(),msgDataBO,detailUrl);
        });
        return AjaxJson.getSuccess();
    }

    public void confirmBusinessItem(long id) {
        TbBusinessItem tbBusinessItem = tbBusinessItemService.getById(id);
        tbBusinessItem.setConfirm(1).setConfirmTime(new Date());
        tbBusinessItemService.updateById(tbBusinessItem);
        TbBusiness tbBusiness=tbBusinessService.getById(tbBusinessItem.getBusinessId());
        //todo 通知作业方
        List<SpAdmin> spAdminList = spAdminService.findByCustomerId(tbBusinessItem.getPickCustomerId());
        MsgDataBO msgDataBO=new MsgDataBO("您有一条新的业务确认提醒",tbBusiness.getCustomerName(), DateUtil.now(),tbBusinessItem.getItemTypeName()+"（"+tbBusinessItem.getItemName()+"）");
        spAdminList.stream().filter(admin -> StrUtil.isNotEmpty(admin.getOpenid())).forEach(admin -> {
            String detailUrl = myConfig.getWebDomain() + "/pages/business-order/business-item?id=" + id;
            wxService.sendTemplateMsg(wxConfig.getBusinessPickTemplate(),admin.getOpenid(),msgDataBO,detailUrl);
        });
    }

    public List<TbBusinessItem> getPartnerBusinessItem(SoMap startPage) {
        return tbBusinessItemService.getList(startPage);
    }
}
