package com.ruoyi.web.v2.v1.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.v2.v1.model.JsCheckDevice;
import com.ruoyi.web.v2.v1.model.JsDeviceMaintenance;
import com.ruoyi.web.v2.v1.mapper.JsCheckDeviceMapper;
import com.ruoyi.web.v2.v1.mapper.JsDeviceMaintenanceMapper;
import com.ruoyi.web.v2.v1.service.IJsCheckDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.web.v2.v1.utils.PhoneNumberValidator;
import com.ruoyi.web.v3.model.response.JsCheckDeviceDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.AjaxResult.error;
import static com.ruoyi.common.core.domain.AjaxResult.success;

/**
 * <p>
 * v2.0设备档案管理 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-05-21
 */
@Service
public class JsCheckDeviceServiceImpl extends ServiceImpl<JsCheckDeviceMapper, JsCheckDevice> implements IJsCheckDeviceService {

    private static final Logger logger = LoggerFactory.getLogger(JsCheckDeviceServiceImpl.class);

    @Autowired
    private JsCheckDeviceMapper checkDeviceMapper;

    @Resource
    private JsDeviceMaintenanceMapper deviceMaintenanceMapper;

    @Override
    public AjaxResult add(JsCheckDevice checkDevice) {
        String deviceName = checkDevice.getDeviceName();
        if (ObjectUtil.isNotEmpty(checkDevice.getPhone())) {
            if (!PhoneNumberValidator.isValidPhoneNumber(checkDevice.getPhone())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return error("手机号码格式不正确！");
            }
        }
        Integer count = checkDeviceMapper.selectCount(new QueryWrapper<JsCheckDevice>().eq("device_name", deviceName)
                .or().eq("device_num",checkDevice.getDeviceNum()));
        if (count != 0) {
            return error("设备档案已存在！");
        } else {
            checkDeviceMapper.insert(checkDevice);
        }
        return success("添加成功");
    }

    @Override
    public AjaxResult edit(JsCheckDevice checkDevice) {
        String deviceName = checkDevice.getDeviceName();
        if (ObjectUtil.isNotEmpty(checkDevice.getPhone())) {
            if (!PhoneNumberValidator.isValidPhoneNumber(checkDevice.getPhone())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return error("手机号码格式不正确！");
            }
        }
        Integer count = checkDeviceMapper.selectCount(new QueryWrapper<JsCheckDevice>().ne("id",checkDevice.getId()).eq("device_name", deviceName));
        if (count != 0) {
            return error("设备档案名称已存在！");
        }
        Integer count1 = checkDeviceMapper.selectCount(new QueryWrapper<JsCheckDevice>().ne("id",checkDevice.getId()).eq("device_num", checkDevice.getDeviceNum()));
        if (count1 != 0) {
            return error("设备档案编号已存在！");
        }
        checkDeviceMapper.updateById(checkDevice);
        return success("修改成功");
    }

    @Override
    public AjaxResult delete(String ids) {
        String[] split = ids.split(",");
        for (String s : split) {
            checkDeviceMapper.deleteById(s);
        }

        return success("删除成功");
    }

    @Override
    public AjaxResult page(Integer pageNum, Integer pageSize, String deviceNum, String deviceName) {
        QueryWrapper<JsCheckDevice> queryWrapper = new QueryWrapper<>();
        Page<JsCheckDevice> page = new Page<>(pageNum, pageSize);
        queryWrapper.like(StringUtils.isNotEmpty(deviceNum), "device_num", deviceNum).or()
                .like(StringUtils.isNotEmpty(deviceName), "device_name", deviceName);
        page  = checkDeviceMapper.selectPage(page, queryWrapper);
        Page<JsCheckDeviceDTO> newPage = new Page<>(pageNum, pageSize);
        newPage.setSize(page.getSize());
        newPage.setTotal(page.getTotal());
        newPage.setPages(page.getPages());
        newPage.setRecords(page.getRecords()
                .stream()
                .filter(Objects::nonNull)  // 过滤非空记录
                .map(this::fixMaintenanceDate)
                .collect(Collectors.toList()));
        return success(newPage);
    }

    @Override
    public AjaxResult listAll() {
        return success(checkDeviceMapper.selectList(null));
    }

    /**
     * 计算维护日期，并补充致返回数据集
     */
    private JsCheckDeviceDTO fixMaintenanceDate(JsCheckDevice checkDevice) {
        JsCheckDeviceDTO result = new JsCheckDeviceDTO();
        BeanUtils.copyProperties(checkDevice, result);
        if(ObjectUtils.isEmpty(checkDevice.getInvestmentTime()) ||
                ( ObjectUtils.isEmpty(checkDevice.getDays()) || checkDevice.getDays() == 0) ) {
            //如果投入使用日期或维护区间是无效值，那么不计算，直接原样返回
            return result;
        }
        try {
            LocalDateTime baseDate = LocalDateTime.parse(checkDevice.getInvestmentTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            long cycles = ChronoUnit.DAYS.between(baseDate, LocalDateTime.now()) / checkDevice.getDays();
            result.setLastDueDate(baseDate.plusDays(cycles * checkDevice.getDays()));
            result.setNextDueDate(result.getLastDueDate().plusDays(checkDevice.getDays()));
            //查询维护登记记录，以便判断是否给出需要维护的提示
            List<JsDeviceMaintenance> records = deviceMaintenanceMapper.selectList(
                    Wrappers.<JsDeviceMaintenance>lambdaQuery()
                            .eq(JsDeviceMaintenance::getDeviceNum, checkDevice.getDeviceNum())
                            .eq(JsDeviceMaintenance::getDeviceName, checkDevice.getDeviceName())
                            .orderByDesc(JsDeviceMaintenance::getId).last("LIMIT 1"));
            if(!ObjectUtils.isEmpty(records) && !ObjectUtils.isEmpty(records.get(0).getMaintenanceTime())) {
                LocalDateTime maintenanceTime = LocalDateTime.parse(records.get(0).getMaintenanceTime(),
                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if(maintenanceTime.toLocalDate().isBefore(result.getLastDueDate().toLocalDate())) {
                    //维护日期在最后约定维护日之前，说明当前需要维护
                    result.setNeedCareImmediately(Boolean.TRUE);
                }
            }else {
                //查询不到任何维护记录，直接判断当前时间和维护日期
                if(LocalDate.now().isAfter(result.getLastDueDate().toLocalDate())) {
                    result.setNeedCareImmediately(Boolean.TRUE);
                }
            }
        }catch (Exception e) {
            logger.error("根据投入使用日期‘ {} ’计算约定维护日发生异常...", checkDevice.getInvestmentTime());
        }
        return result;
    }



}
