package com.hotwj.platform.driverManagement.driver.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.date.DateUtil;
import com.hotwj.platform.driverManagement.driver.domain.bo.DriverRegisterBo;
import com.hotwj.platform.driverManagement.driver.domain.bo.HotDriverBatchBindVehicleBo;
import com.hotwj.platform.driverManagement.driver.domain.bo.HotDriverBo;
import com.hotwj.platform.driverManagement.driver.domain.bo.HotDriverPasswordBo;
import com.hotwj.platform.driverManagement.driver.domain.bo.HotDriverSwitchVehicleBo;
import com.hotwj.platform.driverManagement.driver.domain.vo.HotDriverImportVo;
import com.hotwj.platform.driverManagement.driver.domain.vo.HotDriverLedgerExportVo;
import com.hotwj.platform.driverManagement.driver.domain.vo.HotDriverVo;
import com.hotwj.platform.driverManagement.driver.service.IHotDriverService;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.bo.HotVehicleBo;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.vo.DriverBindingVehicleItemVo;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.vo.DriverBindingVehicleOptionsVo;
import com.hotwj.platform.resourceManagement.vehicleManagement.domain.vo.HotVehicleVo;
import com.hotwj.platform.resourceManagement.vehicleManagement.service.IHotVehicleService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.encrypt.annotation.ApiEncrypt;
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.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * 驾驶员基本信息
 *
 * @author shihongwei
 * @date 2025-12-19
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/driverManagement/driver")
public class HotDriverController extends BaseController {

    private final IHotDriverService hotDriverService;
    private final IHotVehicleService hotVehicleService;

    /**
     * 导入驾驶员
     */
    //@SaCheckPermission("driverManagement:driver:import")
    @Log(title = "驾驶员基本信息", businessType = BusinessType.IMPORT)
    @RepeatSubmit()
    @PostMapping("/importData")
    @Operation(summary = "导入驾驶员信息")
    public R<String> importData(@RequestPart("file") MultipartFile file) throws Exception {
        List<HotDriverImportVo> list = ExcelUtil.importExcel(file.getInputStream(), HotDriverImportVo.class);
        Long companyId = LoginHelper.getLoginUser().getCompanyId();
        return R.ok(hotDriverService.importData(list, companyId));
    }

    /**
     * 查询驾驶员基本信息列表
     */
    //@SaCheckPermission("driverManagement:driver:list")
    @GetMapping("/list")
    public TableDataInfo<HotDriverVo> list(HotDriverBo bo, PageQuery pageQuery) {
        return hotDriverService.queryPageList(bo, pageQuery);
    }

    /**
     * 通过邀请码注册驾驶员
     */
    @SaIgnore
    @Log(title = "驾驶员注册", businessType = BusinessType.INSERT)
    @PostMapping("/register")
    public R<Void> register(@Validated @RequestBody DriverRegisterBo bo) {
        return toAjax(hotDriverService.registerByInviteCode(bo));
    }

    //@SaCheckPermission("driverManagement:driver:list")
    @GetMapping("/stat")
    public R<List<com.hotwj.platform.driverManagement.driver.domain.vo.HotDriverCategoryStatVo>> stat(@RequestParam(required = false) Long companyId) {
        return R.ok(hotDriverService.queryDriverCategoryStat(companyId));
    }

    /**
     * 查询驾驶员已绑定车辆和公司可绑定车辆列表
     */
    @GetMapping("/bindingVehicleOptions")
    @Operation(summary = "查询驾驶员已绑定车辆和公司可绑定车辆列表")
    public R<DriverBindingVehicleOptionsVo> bindingVehicleOptions(@RequestParam Long companyId,
                                                                  @RequestParam String driverId) {
        return R.ok(hotVehicleService.queryDriverBindingVehicleOptions(companyId, driverId));
    }

    /**
     * 查询驾驶员已绑定车辆列表
     */
    @GetMapping("/boundVehicles")
    @Operation(summary = "查询驾驶员已绑定车辆列表")
    public R<List<DriverBindingVehicleItemVo>> boundVehicles(@RequestParam Long companyId,
                                                             @RequestParam String driverId) {
        return R.ok(hotVehicleService.queryDriverBoundVehicleList(companyId, driverId));
    }

    /**
     * 导出驾驶员基本信息列表
     */
    //@SaCheckPermission("driverManagement:driver:export")
    @Log(title = "驾驶员基本信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HotDriverBo bo, HttpServletResponse response) {
        List<HotDriverVo> list = hotDriverService.queryList(bo);
        ExcelUtil.exportExcel(list, "驾驶员基本信息", HotDriverVo.class, response);
    }

    /**
     * 下载导入模板
     */
    @SaIgnore
    @GetMapping("/importTemplate")
    @Operation(summary = "下载驾驶员导入模板")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil.exportExcel(new ArrayList<>(), "驾驶员导入模板", HotDriverImportVo.class, response);
    }

    /**
     * 按导入模板导出驾驶员信息
     */
    //@SaCheckPermission("driverManagement:driver:export")
    @Log(title = "驾驶员导出（导入模板列）", businessType = BusinessType.EXPORT)
    @PostMapping("/exportTemplateData")
    @Operation(summary = "按导入模板导出驾驶员信息")
    public void exportTemplateData(HotDriverBo bo, HttpServletResponse response) {
        List<HotDriverVo> drivers = hotDriverService.queryList(bo);

        HotVehicleBo vehicleBo = new HotVehicleBo();
        vehicleBo.setCompanyId(bo.getCompanyId());
        List<HotVehicleVo> vehicles = hotVehicleService.queryList(vehicleBo);
        Map<String, HotVehicleVo> plateMap = new HashMap<>();
        for (HotVehicleVo v : vehicles) {
            plateMap.put(v.getPlateNumber(), v);
        }

        List<HotDriverImportVo> exportList = new ArrayList<>();
        for (HotDriverVo d : drivers) {
            HotDriverImportVo vo = new HotDriverImportVo();
            vo.setName(d.getName());
            vo.setPhone(d.getPhone());
            vo.setPlateNumber(d.getPlateNumber());
            vo.setIdCardNo(d.getIdCardNo());
            vo.setIdCardExpireDate(resolveExpireDateText(d.getIdCardExpireDate(), d.getIdCardLongTerm()));
            vo.setDriverLicenseFirstIssueDate(d.getDriverLicenseFirstIssueDate());
            vo.setDriverLicenseVehicleType(d.getDriverLicenseVehicleType());
            vo.setDriverLicenseExpireDate(resolveExpireDateText(d.getDriverLicenseExpireDate(), d.getDriverLicenseLongTerm()));
            vo.setDriverLicenseOrg(d.getDriverLicenseOrg());
            vo.setGender(d.getGender());
            vo.setNation(d.getNation());
            vo.setQualificationType(d.getQualificationType());
            vo.setQualificationNo(d.getQualificationNo());
            vo.setQualificationFirstIssueDate(d.getQualificationFirstIssueDate());
            vo.setQualificationValidEndDate(d.getQualificationValidEndDate());
            vo.setQualificationValidStartDate(d.getQualificationValidStartDate());
            vo.setQualificationOrg(d.getQualificationOrg());
            vo.setBirthDate(d.getBirthDate());
            vo.setHouseholdAddress(d.getHouseholdAddress());
            vo.setCurrentAddress(d.getCurrentAddress());
            vo.setEducation(d.getEducation());
            vo.setPoliticalStatus(d.getPoliticalStatus());
            vo.setMaritalStatus(d.getMaritalStatus());
            vo.setHealthStatus(d.getHealthStatus());
            vo.setEntryDate(d.getEntryDate());
            vo.setPersonType(d.getPersonType());
            exportList.add(vo);
        }
        ExcelUtil.exportExcel(exportList, "驾驶员导入模板列导出", HotDriverImportVo.class, response);
    }

    private String resolveExpireDateText(Date expireDate, Long longTermFlag) {
        if (Long.valueOf(1L).equals(longTermFlag)) {
            return "长期";
        }
        if (expireDate == null) {
            return null;
        }
        return DateUtil.formatDate(expireDate);
    }

    /**
     * 驾驶员台账导出
     */
    //@SaCheckPermission("driverManagement:driver:export")
    @Log(title = "驾驶员台账导出", businessType = BusinessType.EXPORT)
    @PostMapping("/ledgerExport")
    @Operation(summary = "驾驶员台账导出")
    public void ledgerExport(HotDriverBo bo, HttpServletResponse response) {
        List<HotDriverVo> drivers = hotDriverService.queryList(bo);

        HotVehicleBo vehicleBo = new HotVehicleBo();
        vehicleBo.setCompanyId(bo.getCompanyId());
        List<HotVehicleVo> vehicles = hotVehicleService.queryList(vehicleBo);
        Map<String, HotVehicleVo> plateMap = new HashMap<>();
        for (HotVehicleVo v : vehicles) {
            plateMap.put(v.getPlateNumber(), v);
        }

        List<HotDriverLedgerExportVo> exportList = new ArrayList<>();
        for (HotDriverVo d : drivers) {
            HotDriverLedgerExportVo vo = new HotDriverLedgerExportVo();
            vo.setName(d.getName());
            vo.setPhone(d.getPhone());
            vo.setIdCardNo(d.getIdCardNo());
            vo.setEntryDate(d.getEntryDate());
            vo.setCurrentAddress(d.getCurrentAddress());
            HotVehicleVo vehicle = plateMap.get(d.getPlateNumber());
            if (vehicle != null) {
                vo.setVehicleArchiveNo(vehicle.getArchiveNo());
                vo.setPlateNumber(vehicle.getPlateNumber());
            } else {
                vo.setPlateNumber(d.getPlateNumber());
            }
            vo.setDriverLicenseNo(d.getDriverLicenseNo());
            vo.setDriverLicenseArchiveNo(d.getDriverLicenseArchiveNo());
            vo.setDriverLicenseVehicleType(d.getDriverLicenseVehicleType());
            vo.setDriverLicenseFirstIssueDate(d.getDriverLicenseFirstIssueDate());
            vo.setDriverLicenseExpireDate(d.getDriverLicenseExpireDate());
            vo.setQualificationNo(d.getQualificationNo());
            vo.setQualificationType(d.getQualificationType());
            vo.setQualificationFirstIssueDate(d.getQualificationFirstIssueDate());
            vo.setQualificationValidEndDate(d.getQualificationValidEndDate());
            exportList.add(vo);
        }
        ExcelUtil.exportExcel(exportList, "驾驶员台账信息", HotDriverLedgerExportVo.class, response);
    }

    /**
     * 获取驾驶员基本信息详细信息
     *
     * @param id 主键
     */
    //@SaCheckPermission("driverManagement:driver:query")
    @GetMapping("/{id}")
    public R<HotDriverVo> getInfo(@NotNull(message = "主键不能为空")
                                  @PathVariable String id) {
        return R.ok(hotDriverService.queryById(id));
    }

    /**
     * 新增驾驶员基本信息
     */
    //@SaCheckPermission("driverManagement:driver:add")
    @Log(title = "驾驶员基本信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody HotDriverBo bo) {
        return toAjax(hotDriverService.insertByBo(bo));
    }

    /**
     * 修改驾驶员基本信息
     */
    //@SaCheckPermission("driverManagement:driver:edit")
    @Log(title = "驾驶员基本信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotDriverBo bo) {
        return toAjax(hotDriverService.updateByBo(bo));
    }

    /**
     * 批量绑定驾驶员车辆
     */
    @Log(title = "驾驶员批量绑定车辆", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/batchBindVehicles")
    @Operation(summary = "批量绑定驾驶员车辆")
    public R<Void> batchBindVehicles(@Validated @RequestBody HotDriverBatchBindVehicleBo bo) {
        return toAjax(hotDriverService.batchBindVehicles(bo));
    }

    /**
     * 追加批量绑定驾驶员车辆
     */
    @Log(title = "驾驶员追加批量绑定车辆", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/appendBindVehicles")
    @Operation(summary = "追加批量绑定驾驶员车辆")
    public R<Void> appendBindVehicles(@Validated @RequestBody HotDriverBatchBindVehicleBo bo) {
        return toAjax(hotDriverService.appendBindVehicles(bo));
    }

    /**
     * 解除驾驶员车辆绑定
     */
    @Log(title = "驾驶员解除车辆绑定", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/unbindVehicles")
    @Operation(summary = "解除驾驶员车辆绑定")
    public R<Void> unbindVehicles(@Validated @RequestBody HotDriverBatchBindVehicleBo bo) {
        return toAjax(hotDriverService.unbindVehicles(bo));
    }

    /**
     * 当前登录驾驶员切换默认车辆
     */
    @Log(title = "驾驶员切换默认车辆", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/switchVehicle")
    @Operation(summary = "当前登录驾驶员切换默认车辆")
    public R<Void> switchVehicle(@Validated @RequestBody HotDriverSwitchVehicleBo bo) {
        return toAjax(hotDriverService.switchVehicle(bo));
    }

    /**
     * 企业负责人修改驾驶员登录密码
     *
     * @param id 驾驶员ID
     * @param bo 密码信息
     * @return 是否成功
     */
    @ApiEncrypt
    @Log(title = "驾驶员密码", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/{id}/password")
    @Operation(summary = "企业负责人修改驾驶员登录密码")
    public R<Void> updatePassword(@PathVariable String id, @Validated @RequestBody HotDriverPasswordBo bo) {
        return toAjax(hotDriverService.updatePassword(id, bo.getNewPassword()));
    }

    /**
     * 删除驾驶员基本信息
     *
     * @param ids 主键串
     */
    //@SaCheckPermission("driverManagement:driver:remove")
    @Log(title = "驾驶员基本信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(hotDriverService.deleteWithValidByIds(List.of(ids), true));
    }

    /**
     * 审核驾驶员
     *
     * @param id          驾驶员ID
     * @param auditStatus 审核状态
     */
    //@SaCheckPermission("driverManagement:driver:edit")
    @Log(title = "驾驶员审核", businessType = BusinessType.UPDATE)
    @PutMapping("/audit/{id}/{auditStatus}")
    public R<Void> audit(@PathVariable String id, @PathVariable Integer auditStatus) {
        return toAjax(hotDriverService.auditDriver(id, auditStatus));
    }
}
