package com.ylx.massage.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ylx.common.exception.ServiceException;
import com.ylx.common.utils.StringUtils;
import com.ylx.massage.domain.MaTechnician;
import com.ylx.massage.domain.TFareFreeRule;
import com.ylx.massage.domain.TXiangmu;
import com.ylx.massage.domain.vo.FareFreeRuleVo;
import com.ylx.massage.mapper.TFareFreeRuleMapper;
import com.ylx.massage.service.IMaTechnicianService;
import com.ylx.massage.service.TFareFreeRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 免车费规则服务实现类
 *
 * @author system
 * @since 2024-01-13
 */
@Slf4j
@Service
public class TFareFreeRuleServiceImpl extends ServiceImpl<TFareFreeRuleMapper, TFareFreeRule> implements TFareFreeRuleService {

    @Resource
    private IMaTechnicianService jsService;

    /**
     * 新增免车费规则
     *
     * @param fareFreeRule 免车费规则
     * @return boolean 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addFareFreeRule(TFareFreeRule fareFreeRule) {
        // 1. 参数校验
        validateFareFreeRule(fareFreeRule);

        // 2. 检查是否存在启用的规则
        LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TFareFreeRule::getTechId, fareFreeRule.getTechId()).eq(TFareFreeRule::getEnable, 1)
                .eq(TFareFreeRule::getProjectId, fareFreeRule.getProjectId());
        long count = this.count(wrapper);
        if (count > 0) {
            throw new ServiceException("已存在启用的免车费规则，请先禁用后再添加");
        }

        // 3. 设置时间
        fareFreeRule.setCreateTime(LocalDateTime.now());
        fareFreeRule.setUpdateTime(LocalDateTime.now());

        // 4. 保存
        return this.save(fareFreeRule);
    }

    /**
     * 保存免车费规则（支持新增和修改）
     * 如果传入id则更新，否则新增
     *
     * 业务流程：
     * 1. 参数校验
     * 2. 判断是新增还是修改（根据id是否为空）
     * 3. 新增：检查是否存在启用的规则，不允许重复添加
     * 4. 修改：更新规则信息
     * 5. 设置时间并保存
     *
     * @param fareFreeRule 免车费规则
     * @return boolean 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveFareFreeRule(TFareFreeRule fareFreeRule) {
        // 1. 参数校验
        validateFareFreeRule(fareFreeRule);

        // 2. 判断是新增还是修改
        if (StringUtils.isNotBlank(fareFreeRule.getId())) {
            // ========== 修改场景 ==========
            log.info("修改免车费规则，规则ID：{}", fareFreeRule.getId());

            // 2.1 查询原规则是否存在
            TFareFreeRule existingRule = this.getById(fareFreeRule.getId());
            if (existingRule == null) {
                throw new ServiceException("免车费规则不存在");
            }

            // 2.2 如果修改的是启用状态，需要检查是否与其他启用的规则冲突
            if ("1".equals(fareFreeRule.getEnable())) {
                LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(TFareFreeRule::getTechId, fareFreeRule.getTechId())
                        .eq(TFareFreeRule::getProjectId, fareFreeRule.getProjectId())
                        .eq(TFareFreeRule::getTimeRange1, fareFreeRule.getTimeRange1())
                        .eq(TFareFreeRule::getTimeRange2, fareFreeRule.getTimeRange2())
                        .eq(TFareFreeRule::getEnable, 1)
                        .ne(TFareFreeRule::getId, fareFreeRule.getId()); // 排除当前规则
                long count = this.count(wrapper);
                if (count > 0) {
                    throw new ServiceException("已存在启用的免车费规则，请先禁用后再启用");
                }
            }

            // 2.3 设置更新时间
            fareFreeRule.setUpdateTime(LocalDateTime.now());
            // 2.4 更新
            return this.updateById(fareFreeRule);
        } else {
            // ========== 新增场景 ==========
            //根据openID获取技师的信息
//            TJs js = jsService.getOne(new LambdaQueryWrapper<TJs>().eq(TJs::getcOpenId, fareFreeRule.getOpenId()));
            MaTechnician js = jsService.getOne(new LambdaQueryWrapper<MaTechnician>().eq(MaTechnician::getId, fareFreeRule.getTechId()));
            if (js == null) {
                throw new ServiceException("技师不存在");
            }
            fareFreeRule.setTechId(js.getId().toString());

            // 2.5 检查是否存在启用的规则（同一技师、同一项目）
            if ("1".equals(fareFreeRule.getEnable())) {
                LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(TFareFreeRule::getTechId, fareFreeRule.getTechId())
                        .eq(TFareFreeRule::getEnable, 1)
                        .eq(TFareFreeRule::getProjectId, fareFreeRule.getProjectId());
                long count = this.count(wrapper);
                if (count > 0) {
                    throw new ServiceException("已存在启用的免车费规则，请先禁用后再添加");
                }
            }

            // 2.6 设置时间
            fareFreeRule.setCreateTime(LocalDateTime.now());
            fareFreeRule.setUpdateTime(LocalDateTime.now());
            // 2.7 保存
            return this.save(fareFreeRule);
        }
    }

     /**
     * 禁用免车费规则（H5 技师端）
     *
     * @param
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean disableFareFreeRule(String openId,String enable) {
        //根据openId查询技师信息
        MaTechnician js = jsService.getOne(new LambdaQueryWrapper<MaTechnician>().eq(MaTechnician::getId, openId));
        if (js == null) {
            throw new ServiceException("技师不存在");
        }
        String techId = js.getId().toString();
        LambdaQueryWrapper<TFareFreeRule> eq = new LambdaQueryWrapper<TFareFreeRule>().eq(TFareFreeRule::getTechId, techId).orderByDesc(TFareFreeRule::getCreateTime).last("limit 1");
        TFareFreeRule existingRule = this.getOne(eq);
        if (existingRule == null) {
            throw new ServiceException("免车费规则不存在");
        }
        //设置状态
        existingRule.setEnable(enable);
        existingRule.setUpdateTime(LocalDateTime.now());
        return this.updateById(existingRule);
    }

    /**
     * 查询免车费规则列表
     *
     * @param openId 技师ID
     * @return List<FareFreeRuleVo> 免车费规则VO列表
     */
    @Override
    public FareFreeRuleVo listFareFreeRules(String openId) {
        //根据openId查询技师信息
        MaTechnician js = jsService.getOne(new LambdaQueryWrapper<MaTechnician>().eq(MaTechnician::getId, openId));
        if (js == null) {
            throw new ServiceException("技师不存在");
        }
        String techId = js.getId().toString();
        // 1. 查询规则列表
        LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TFareFreeRule::getTechId, techId).eq(TFareFreeRule::getEnable, 1)
                .orderByDesc(TFareFreeRule::getCreateTime);
        TFareFreeRule fareFreeRule = this.getOne(wrapper);
        // 2. 转换为VO
        return Optional.ofNullable(fareFreeRule).map(rule -> {
            FareFreeRuleVo vo = new FareFreeRuleVo();
            BeanUtils.copyProperties(rule, vo);


            // 查询项目名称
            if (StringUtils.isNotBlank(rule.getProjectId())) {
                String projectNames = "";
//                TXiangmu xiangmu = xiangmuService.getById(rule.getProjectId());
//                if (xiangmu != null && StringUtils.isNotBlank(xiangmu.getcTitle())) {
//                    projectNames = xiangmu.getcTitle();
//                }
                vo.setProjectNames(projectNames.isEmpty() ? null : projectNames);
            }
            return vo;
        }).orElse(null);
    }

    /**
     * 判断订单是否满足免车费条件
     *
     * @param projectIds 服务项目ID列表
     * @param distance   订单距离（公里）
     * @param deptId     部门ID
     * @return true-免车费，false-不免车费
     */
    @Override
    public boolean isFareFree(List<String> projectIds, Integer distance, String deptId) {
        // 1. 参数校验
        if (CollectionUtil.isEmpty(projectIds) || distance == null || distance <= 0) {
            return false;
        }

        // 2. 查询启用的免车费规则
        LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TFareFreeRule::getTechId, deptId)
                .eq(TFareFreeRule::getEnable, 1)
                .eq(TFareFreeRule::getIsDelete, 0)
                .last("LIMIT 1");
        TFareFreeRule rule = this.getOne(wrapper);

        // 3. 如果没有启用的规则，不免车费
        if (rule == null) {
            return false;
        }

        // 4. 校验服务项目（订单的项目ID必须在规则的项目ID列表中）
        if (StringUtils.isBlank(rule.getProjectId())) {
            return false;
        }
        boolean projectMatch = projectIds.stream()
                .anyMatch(projectId -> rule.getProjectId().equals(projectId));
        if (!projectMatch) {
            return false;
        }

        // 5. 校验距离（订单距离必须 >= 规则的最小距离）
        if (distance < rule.getMinDistance()) {
            return false;
        }

        // 6. 所有条件满足，免车费
        return true;
    }

    /**
     * 校验免车费规则参数
     *
     * @param fareFreeRule 免车费规则
     */
    private void validateFareFreeRule(TFareFreeRule fareFreeRule) {
//        // 校验openID
//        if(StringUtils.isBlank(fareFreeRule.getOpenId())){
//            throw new ServiceException("openID不能为空");
//        }
        // 校验服务项目
        if (StringUtils.isBlank(fareFreeRule.getProjectId())) {
            throw new ServiceException("请至少选择一个服务项目");
        }

        //  校验时间段
        if (StringUtils.isBlank(fareFreeRule.getTimeRange1())) {
            throw new ServiceException("服务时间段1不能为空");
        }

        if (StringUtils.isBlank(fareFreeRule.getTimeRange2())) {
            throw new ServiceException("服务时间段2不能为空");
        }

        // 校验时间段格式
        // 校验时间格式
        if (!fareFreeRule.getTimeRange1().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]-([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")) {
            throw new ServiceException("时间格式错误，请使用 HH:mm 格式（如：08:00）");
        }
        // 校验时间格式
        if (!fareFreeRule.getTimeRange2().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]-([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")) {
            throw new ServiceException("时间格式错误，请使用 HH:mm 格式（如：08:00）");
        }

        // 校验距离
        if (fareFreeRule.getMinDistance() == null || fareFreeRule.getMinDistance() <= 0) {
            throw new ServiceException("订单距离必须大于0");
        }

        // 校验是否启用
        if (fareFreeRule.getEnable() == null || (!"0".equals(fareFreeRule.getEnable()) && !"1".equals(fareFreeRule.getEnable()))) {
            throw new ServiceException("是否启用参数错误");
        }
    }
}
