package com.hotwj.platform.config.vehicleSecondaryMaintenanceConfig.controller;

import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.vehicleSecondaryMaintenanceConfig.domain.bo.HotVehicleSecondaryMaintenanceConfigBo;
import com.hotwj.platform.config.vehicleSecondaryMaintenanceConfig.domain.vo.HotVehicleSecondaryMaintenanceConfigVo;
import com.hotwj.platform.config.vehicleSecondaryMaintenanceConfig.service.IHotVehicleSecondaryMaintenanceConfigService;
import com.hotwj.platform.resourceManagement.vehicleMaintenance.domain.vo.HotVehicleMaintenanceVo;
import com.hotwj.platform.resourceManagement.vehicleMaintenance.service.IHotVehicleMaintenanceService;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.bo.HotVehicleStatusBo;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.vo.HotVehicleVo;
import com.hotwj.platform.resourceManagement.vehicleManagement.service.IHotVehicleService;
import com.hotwj.platform.resourceManagement.vehicleManagement.utils.VehicleUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 车辆二级维护配置
 *
 * @author shihongwei
 * @date 2025-12-19
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/vehicleSecondaryMaintenanceConfig")
@Tag(name = "车辆二级维护配置", description = "车辆二级维护配置增删改查与导出")
public class HotVehicleSecondaryMaintenanceConfigController extends BaseController {

    private final IHotVehicleSecondaryMaintenanceConfigService hotVehicleSecondaryMaintenanceConfigService;
    private final IHotVehicleService hotVehicleService;
    private final IHotVehicleMaintenanceService hotVehicleMaintenanceService;

    private static LocalDate toLocalDate(Date date) {
        if (date == null) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

	
    /**
     * 查询车辆二级维护配置列表
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:list")
    @GetMapping("/list")
    @Operation(summary = "查询车辆二级维护配置列表")
    public TableDataInfo<HotVehicleSecondaryMaintenanceConfigVo> list(HotVehicleSecondaryMaintenanceConfigBo bo, PageQuery pageQuery) {
        return hotVehicleSecondaryMaintenanceConfigService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出车辆二级维护状态列表
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:export")
    @Log(title = "车辆二级维护状态", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @Operation(summary = "导出车辆二级维护状态列表")
    public void export(HotVehicleStatusBo bo, HttpServletResponse response) {
        Long companyId = bo != null ? bo.getCompanyId() : null;
        if (companyId == null) {
            ExcelUtil.exportExcel(new ArrayList<>(), "车辆二级维护", VehicleSecondaryMaintenanceExportVo.class, response);
            return;
        }

        HotVehicleSecondaryMaintenanceConfigBo configBo = new HotVehicleSecondaryMaintenanceConfigBo();
        configBo.setCompanyId(companyId);
        configBo.setIsEnabled(1L);
        configBo.setIsDeleted(0L);
        List<HotVehicleSecondaryMaintenanceConfigVo> configs = hotVehicleSecondaryMaintenanceConfigService.queryList(configBo);
        configs = configs == null ? new ArrayList<>() : configs.stream()
                .filter(c -> c != null && (c.getIsEnabled() == null || c.getIsEnabled() == 1L))
                .sorted(Comparator.comparing(c -> c.getIntervalYears() == null ? Long.MAX_VALUE : c.getIntervalYears()))
                .toList();

        List<VehicleUtils.AnnualInspectionRule> rules = new ArrayList<>();
        for (HotVehicleSecondaryMaintenanceConfigVo c : configs) {
            if (c.getIntervalYears() == null || c.getInspectionTimes() == null) {
                continue;
            }
            rules.add(new VehicleUtils.AnnualInspectionRule(c.getIntervalYears().intValue(), c.getInspectionTimes().intValue()));
        }

        if (bo == null) {
            bo = new HotVehicleStatusBo();
        }
        bo.setCompanyId(companyId);
        PageQuery pageQuery = new PageQuery(Integer.MAX_VALUE, PageQuery.DEFAULT_PAGE_NUM);
        TableDataInfo<HotVehicleVo> vehiclePage = hotVehicleService.queryPageListByStatus(bo, pageQuery);
        List<HotVehicleVo> vehicles = vehiclePage.getRows();
        if (vehicles == null || vehicles.isEmpty()) {
            ExcelUtil.exportExcel(new ArrayList<>(), "车辆二级维护", VehicleSecondaryMaintenanceExportVo.class, response);
            return;
        }

        List<VehicleSecondaryMaintenanceExportVo> rows = buildSecondaryMaintenanceExportRows(vehicles, rules);
        ExcelUtil.exportExcel(rows, "车辆二级维护", VehicleSecondaryMaintenanceExportVo.class, response);
    }

    /**
     * 获取车辆二级维护配置详细信息
     *
     * @param id 主键
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:query")
    @GetMapping("/{id}")
    @Operation(summary = "获取车辆二级维护配置详细信息")
    public R<HotVehicleSecondaryMaintenanceConfigVo> getInfo(@NotNull(message = "主键不能为空")
                                                             @PathVariable Long id) {
        return R.ok(hotVehicleSecondaryMaintenanceConfigService.queryById(id));
    }

    /**
     * 新增车辆二级维护配置
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:add")
    @Log(title = "车辆二级维护配置", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    @Operation(summary = "新增车辆二级维护配置")
    public R<Void> add(@Validated(AddGroup.class) @RequestBody HotVehicleSecondaryMaintenanceConfigBo bo) {
        return toAjax(hotVehicleSecondaryMaintenanceConfigService.insertByBo(bo));
    }

    /**
     * 修改车辆二级维护配置
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:edit")
    @Log(title = "车辆二级维护配置", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    @Operation(summary = "修改车辆二级维护配置")
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotVehicleSecondaryMaintenanceConfigBo bo) {
        return toAjax(hotVehicleSecondaryMaintenanceConfigService.updateByBo(bo));
    }

    /**
     * 删除车辆二级维护配置
     *
     * @param ids 主键串
     */
    //@SaCheckPermission("config:vehicleSecondaryMaintenanceConfig:remove")
    @Log(title = "车辆二级维护配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @Operation(summary = "删除车辆二级维护配置")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(hotVehicleSecondaryMaintenanceConfigService.deleteWithValidByIds(List.of(ids), true));
    }

    private static Date toDate(LocalDate date) {
        if (date == null) {
            return null;
        }
        return Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    private List<VehicleSecondaryMaintenanceExportVo> buildSecondaryMaintenanceExportRows(List<HotVehicleVo> vehicles, List<VehicleUtils.AnnualInspectionRule> rules) {
        List<VehicleSecondaryMaintenanceExportVo> rows = new ArrayList<>();
        for (HotVehicleVo v : vehicles) {
            if (v == null) {
                continue;
            }
            VehicleSecondaryMaintenanceExportVo row = new VehicleSecondaryMaintenanceExportVo();
            row.setPlateNumber(v.getPlateNumber());

            Date issueDate = v.getCertificateIssueDate();
            row.setIssueDate(issueDate);

            HotVehicleMaintenanceVo lastMaintenance = v.getId() != null ? hotVehicleMaintenanceService.queryLatestByVehicleId(v.getId()) : null;
            Date lastMaintenanceTime = null;
            if (lastMaintenance != null) {
                lastMaintenanceTime = lastMaintenance.getFinishTime() != null ? lastMaintenance.getFinishTime() : lastMaintenance.getMaintainDate();
            }
            row.setLastMaintenanceTime(lastMaintenanceTime != null ? DateUtils.formatDate(lastMaintenanceTime) : "未上传信息");

            LocalDate registrationDate = toLocalDate(issueDate);
            LocalDate lastMaintenanceDate = toLocalDate(lastMaintenanceTime);

            VehicleUtils.InspectionResult result = VehicleUtils.calculateMaintenanceStatus(rules, registrationDate, lastMaintenanceDate);
            if (result == null) {
                rows.add(row);
                continue;
            }

            int times = result.getInspectionTimes();
            row.setMaintenanceTimesText("每年维护(" + times + "次)");
            row.setDueDate(toDate(result.getNextInspectionDate()));
            row.setWarningLevelText(result.getWarningLevelDesc());

            if (result.getWarningLevel() == 6) {
                row.setMaintenanceTip("无需办理");
            } else if (result.getOverdueDays() > 0) {
                row.setMaintenanceTip("已到期(" + result.getOverdueDays() + "天)");
            } else if (result.getRemainingDays() > 0) {
                row.setMaintenanceTip("剩余(" + result.getRemainingDays() + "天)到期");
            } else {
                row.setMaintenanceTip("已到期(0天)");
            }

            rows.add(row);
        }
        return rows;
    }

    @GetMapping("/maintenanceStatus/list")
    @Operation(summary = "车辆二级维护状态列表")
    public TableDataInfo<VehicleSecondaryMaintenanceStatusVo> maintenanceStatusList(HotVehicleStatusBo bo, PageQuery pageQuery) {
        Long companyId = bo != null ? bo.getCompanyId() : null;
        if (companyId == null) {
            return new TableDataInfo<>(new ArrayList<>(), 0);
        }

        HotVehicleSecondaryMaintenanceConfigBo configBo = new HotVehicleSecondaryMaintenanceConfigBo();
        configBo.setCompanyId(companyId);
        configBo.setIsEnabled(1L);
        configBo.setIsDeleted(0L);
        List<HotVehicleSecondaryMaintenanceConfigVo> configs = hotVehicleSecondaryMaintenanceConfigService.queryList(configBo);
        configs = configs == null ? new ArrayList<>() : configs.stream()
                .filter(c -> c != null && (c.getIsEnabled() == null || c.getIsEnabled() == 1L))
                .sorted(Comparator.comparing(c -> c.getIntervalYears() == null ? Long.MAX_VALUE : c.getIntervalYears()))
                .toList();

        List<VehicleUtils.AnnualInspectionRule> rules = new ArrayList<>();
        for (HotVehicleSecondaryMaintenanceConfigVo c : configs) {
            if (c.getIntervalYears() == null || c.getInspectionTimes() == null) {
                continue;
            }
            rules.add(new VehicleUtils.AnnualInspectionRule(c.getIntervalYears().intValue(), c.getInspectionTimes().intValue()));
        }

        TableDataInfo<HotVehicleVo> vehiclePage = hotVehicleService.queryPageListByStatus(bo, pageQuery);
        List<HotVehicleVo> vehicles = vehiclePage.getRows();
        if (vehicles == null || vehicles.isEmpty()) {
            return new TableDataInfo<>(new ArrayList<>(), vehiclePage.getTotal());
        }

        List<VehicleSecondaryMaintenanceStatusVo> rows = new ArrayList<>();
        for (HotVehicleVo v : vehicles) {
            if (v == null) {
                continue;
            }
            VehicleSecondaryMaintenanceStatusVo row = new VehicleSecondaryMaintenanceStatusVo();
            row.setVehicleId(v.getId());
            row.setPlateNumber(v.getPlateNumber());

            Date issueDate = v.getCertificateIssueDate();
            row.setIssueDate(issueDate);

            HotVehicleMaintenanceVo lastMaintenance = v.getId() != null ? hotVehicleMaintenanceService.queryLatestByVehicleId(v.getId()) : null;
            Date lastMaintenanceTime = null;
            if (lastMaintenance != null) {
                lastMaintenanceTime = lastMaintenance.getFinishTime() != null ? lastMaintenance.getFinishTime() : lastMaintenance.getMaintainDate();
            }
            row.setLastMaintenanceTime(lastMaintenanceTime);

            LocalDate registrationDate = toLocalDate(issueDate);
            LocalDate lastMaintenanceDate = toLocalDate(lastMaintenanceTime);

            VehicleUtils.InspectionResult result = VehicleUtils.calculateMaintenanceStatus(rules, registrationDate, lastMaintenanceDate);

            if (result != null) {
                int times = result.getInspectionTimes();
                row.setMaintenanceTimesText("每年维护(" + times + "次)");

                LocalDate dueLocalDate = result.getNextInspectionDate();
                row.setDueDate(toDate(dueLocalDate));
                row.setWarningLevel(result.getWarningLevel());
                row.setWarningLevelText(result.getWarningLevelDesc());

                if (result.getWarningLevel() == 6) {
                    row.setMaintenanceTip("无需办理");
                } else if (result.getOverdueDays() > 0) {
                    row.setMaintenanceTip("已到期(" + result.getOverdueDays() + "天)");
                } else if (result.getRemainingDays() > 0) {
                    row.setMaintenanceTip("剩余(" + result.getRemainingDays() + "天)到期");
                } else {
                    row.setMaintenanceTip("已到期(0天)");
                }
            }

            rows.add(row);
        }

        return new TableDataInfo<>(rows, vehiclePage.getTotal());
    }

    @Data
    public static class VehicleSecondaryMaintenanceStatusVo {
        private String vehicleId;
        private String plateNumber;
        private String maintenanceTimesText;
        private String maintenanceTip;
        private Date lastMaintenanceTime;
        private Date issueDate;
        private Date dueDate;
        private Integer warningLevel;
        private String warningLevelText;
    }

    @Data
    @ExcelIgnoreUnannotated
    public static class VehicleSecondaryMaintenanceExportVo {
        @ExcelProperty(value = "车牌号", index = 0)
        private String plateNumber;

        @ExcelProperty(value = "每年维护次数", index = 1)
        private String maintenanceTimesText;

        @ExcelProperty(value = "维护提示", index = 2)
        private String maintenanceTip;

        @ExcelProperty(value = "最近维护时间", index = 3)
        private String lastMaintenanceTime;

        @ExcelProperty(value = "行驶证发证日期", index = 4)
        private Date issueDate;

        @ExcelProperty(value = "到期日期", index = 5)
        private Date dueDate;

        @ExcelProperty(value = "提示等级", index = 6)
        private String warningLevelText;
    }
}
