package com.ylx.massage.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ylx.common.constant.MassageConstants;
import com.ylx.common.core.domain.entity.SysDictData;
import com.ylx.common.exception.ServiceException;
import com.ylx.common.utils.DictUtils;
import com.ylx.common.utils.StringUtils;
import com.ylx.massage.domain.vo.TFareSettingVo;
import com.ylx.massage.mapper.TFareSettingMapper;
import com.ylx.massage.domain.TFareSetting;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ylx.massage.service.TFareSettingService;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 车费设置表(TFareSetting)表服务实现类
 *
 * @author makejava
 * @since 2024-08-22 17:41:00
 */
@Slf4j
@Service("tFareSettingService")
public class TFareSettingServiceImpl extends ServiceImpl<TFareSettingMapper, TFareSetting> implements TFareSettingService {
    private static final String DAY_TIME = "day_time";

    @Override
    public boolean add(TFareSetting tFareSetting) {
        //判断部门重复设置
        if (tFareSetting.getEnable().equals(MassageConstants.INTEGER_ONE)) {
            LambdaQueryWrapper<TFareSetting> tFareSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
            tFareSettingLambdaQueryWrapper.eq(TFareSetting::getCityCode, tFareSetting.getCityCode())
                    .eq(TFareSetting::getEnable, MassageConstants.INTEGER_ONE);
            List<TFareSetting> fareSettings = this.list(tFareSettingLambdaQueryWrapper);
            if (!Collections.isEmpty(fareSettings)) {
                throw new ServiceException("该城市已有启用的设置");
            }
        }
        boolean save = this.save(tFareSetting);
        if(!save){
            throw new ServiceException("新增失败");
        }
        return save;
    }

    @Override
    public boolean updateFareSetting(TFareSetting tFareSetting) {
        if (tFareSetting.getEnable().equals(MassageConstants.INTEGER_ONE)) {
            LambdaQueryWrapper<TFareSetting> tFareSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
            tFareSettingLambdaQueryWrapper.eq(TFareSetting::getCityCode, tFareSetting.getCityCode()).eq(TFareSetting::getEnable, MassageConstants.INTEGER_ONE);
            //该部门已启用的
            List<TFareSetting> fareSettings = this.list(tFareSettingLambdaQueryWrapper);
            if (!Collections.isEmpty(fareSettings)) {
                if(!fareSettings.get(MassageConstants.INTEGER_ZERO).getId().equals(tFareSetting.getId())){
                    throw new ServiceException("该城市已有启用的设置");
                }
            }
        }
        boolean b = this.updateById(tFareSetting);
        if(!b){
            throw new ServiceException("更新失败");
        }
        return b;
    }

    /**
     * C端根据城市编码和用户预约时间获取车费起步价配置
     * @param cityCode
     * @return
     */
    @Override
    public TFareSettingVo getFareSetting(LocalDateTime userbookingTime, String cityCode) {
        // 参数校验
        if (ObjectUtil.isNull(userbookingTime) || StringUtils.isBlank(cityCode)) {
            throw new IllegalArgumentException("预约时间和城市编码不能为空");
        }

        // 查询最新的有效配置
        TFareSetting setting = getLatestValidFareSetting(cityCode);
        if (setting == null) {
            return null;
        }

        // 解析预约时间
        Date bookingDate = DateUtil.date(userbookingTime);;
        Calendar cal = Calendar.getInstance();
        cal.setTime(bookingDate);
        LocalTime bookingTime = LocalTime.of(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
        // 定义白天时间段（比如 6:00 - 22:00），读取字典表配置
        List<SysDictData> dataDayTimes = DictUtils.getSortedDictCache(DAY_TIME);
        if (dataDayTimes == null || dataDayTimes.size() < 2) {
            throw new IllegalStateException("白天时段字典配置缺失，请检查 dat_time 类型");
        }
        LocalTime dayStart, dayEnd;
        try {
            dayStart = LocalTime.parse(dataDayTimes.get(0).getDictValue());
            dayEnd = LocalTime.parse(dataDayTimes.get(1).getDictValue());
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("白天时段配置格式错误，应为 HH:mm");
        }
        boolean isDaytime = !bookingTime.isBefore(dayStart) && !bookingTime.isAfter(dayEnd);


        TFareSettingVo vo = new TFareSettingVo();
        if (isDaytime) {
            vo.setBaseFare(setting.getDaytimeBaseFare());
            vo.setBaseDistance(setting.getDaytimeBaseDistance());
            vo.setAdditionalFarePer(setting.getDaytimeAdditionalFarePer());
        } else {
            vo.setBaseFare(setting.getNightBaseFare());
            vo.setBaseDistance(setting.getNightBaseDistance());
            vo.setAdditionalFarePer(setting.getNightAdditionalFarePer());
        }
        return vo;
    }

    /**
     * 根据城市编码获取最新的有效车费配置
     */
    private TFareSetting getLatestValidFareSetting(String cityCode) {
        LambdaQueryWrapper<TFareSetting> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TFareSetting::getCityCode, cityCode)
                .eq(TFareSetting::getEnable, 1)
                .eq(TFareSetting::getIsDelete, 0)
                .orderByDesc(TFareSetting::getCreateTime)
                .last("LIMIT 1");
        return this.getOne(wrapper);
    }
}

