package com.sundot.airport.web.controller.ledger;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.sundot.airport.common.annotation.Log;
import com.sundot.airport.common.core.controller.BaseController;
import com.sundot.airport.common.core.domain.AjaxResult;
import com.sundot.airport.common.enums.BusinessType;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.ledger.domain.*;
import com.sundot.airport.ledger.service.*;
import com.sundot.airport.ledger.service.ILedgerCombinedImportService;
import com.sundot.airport.ledger.domain.LedgerDailyTraining;
import com.sundot.airport.ledger.domain.LedgerLeaderDuty;
import com.sundot.airport.ledger.domain.LedgerHealthSoldier;
import com.sundot.airport.ledger.domain.LedgerDormFireSafety;
import com.sundot.airport.ledger.domain.LedgerTrainingIssue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 台账一键导入Controller
 * 提供所有台账类型的 Excel 批量上传接口
 */
@RestController
@RequestMapping("/ledger/import")
public class LedgerImportController extends BaseController {

    @Autowired private ILedgerSupervisionProblemService supervisionProblemService;
    @Autowired private ILedgerPatrolInspectionService patrolInspectionService;
    @Autowired private ILedgerRealtimeInterceptionService realtimeInterceptionService;
    @Autowired private ILedgerServicePatrolService servicePatrolService;
    @Autowired private ILedgerComplaintService complaintService;
    @Autowired private ILedgerSecurityTestService securityTestService;
    @Autowired private ILedgerChannelPassRateService channelPassRateService;
    @Autowired private ILedgerUnsafeEventService unsafeEventService;
    @Autowired private ILedgerSeizureStatsService seizureStatsService;
    @Autowired private ILedgerTerminalBonusService terminalBonusService;
    @Autowired private ILedgerExamScoreService examScoreService;
    @Autowired private ILedgerRewardApprovalService rewardApprovalService;
    @Autowired private ILedgerCombinedImportService combinedImportService;
    @Autowired private ILedgerDailyTrainingService dailyTrainingService;
    @Autowired private ILedgerLeaderDutyService leaderDutyService;
    @Autowired private ILedgerHealthSoldierService healthSoldierService;
    @Autowired private ILedgerDormFireSafetyService dormFireSafetyService;
    @Autowired private ILedgerTrainingIssueService trainingIssueService;
    @Autowired private ILedgerRewardPenaltyService rewardPenaltyService;
    @Autowired private ILedgerLeaveSpecialService leaveSpecialService;
    @Autowired private ILedgerBannerLetterService bannerLetterService;


    private String generateBatchNo() {
        return DateUtils.dateTimeNow("yyyyMMddHHmmss") + UUID.randomUUID().toString().substring(0, 6).toUpperCase();
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:supervision')")
    @Log(title = "台账导入-部门监察问题", businessType = BusinessType.IMPORT)
    @PostMapping("/supervisionProblem")
    public AjaxResult importSupervisionProblem(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerSupervisionProblem> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerSupervisionProblem.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        supervisionProblemService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:patrol')")
    @Log(title = "台账导入-队室三级质控巡查", businessType = BusinessType.IMPORT)
    @PostMapping("/patrolInspection")
    public AjaxResult importPatrolInspection(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerPatrolInspection> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerPatrolInspection.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        patrolInspectionService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:interception')")
    @Log(title = "台账导入-实时质控拦截", businessType = BusinessType.IMPORT)
    @PostMapping("/realtimeInterception")
    public AjaxResult importRealtimeInterception(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerRealtimeInterception> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerRealtimeInterception.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        realtimeInterceptionService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:servicePatrol')")
    @Log(title = "台账导入-服务巡查", businessType = BusinessType.IMPORT)
    @PostMapping("/servicePatrol")
    public AjaxResult importServicePatrol(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerServicePatrol> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerServicePatrol.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        servicePatrolService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:complaint')")
    @Log(title = "台账导入-投诉情况", businessType = BusinessType.IMPORT)
    @PostMapping("/complaint")
    public AjaxResult importComplaint(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerComplaint> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerComplaint.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        complaintService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:securityTest')")
    @Log(title = "台账导入-安保测试", businessType = BusinessType.IMPORT)
    @PostMapping("/securityTest")
    public AjaxResult importSecurityTest(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerSecurityTest> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerSecurityTest.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        securityTestService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:channelPassRate')")
    @Log(title = "台账导入-通道过检率", businessType = BusinessType.IMPORT)
    @PostMapping("/channelPassRate")
    public AjaxResult importChannelPassRate(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerChannelPassRate> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerChannelPassRate.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        channelPassRateService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:unsafeEvent')")
    @Log(title = "台账导入-不安全事件", businessType = BusinessType.IMPORT)
    @PostMapping("/unsafeEvent")
    public AjaxResult importUnsafeEvent(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerUnsafeEvent> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerUnsafeEvent.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        unsafeEventService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:seizureStats')")
    @Log(title = "台账导入-查获违规品统计", businessType = BusinessType.IMPORT)
    @PostMapping("/seizureStats")
    public AjaxResult importSeizureStats(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerSeizureStats> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerSeizureStats.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        seizureStatsService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:terminalBonus')")
    @Log(title = "台账导入-航站楼加分", businessType = BusinessType.IMPORT)
    @PostMapping("/terminalBonus")
    public AjaxResult importTerminalBonus(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerTerminalBonus> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerTerminalBonus.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        terminalBonusService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:examScore')")
    @Log(title = "台账导入-成绩收集", businessType = BusinessType.IMPORT)
    @PostMapping("/examScore")
    public AjaxResult importExamScore(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerExamScore> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerExamScore.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        examScoreService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:rewardApproval')")
    @Log(title = "台账导入-小额奖励审批单", businessType = BusinessType.IMPORT)
    @PostMapping("/rewardApproval")
    public AjaxResult importRewardApproval(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerRewardApproval> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerRewardApproval.class,
                new SimpleListener<>(list)).sheet().doRead();
        list.forEach(item -> {
            item.setImportBatch(batchNo);
            item.setSourceType("1");
            item.setCreateBy(getUsername());
        });
        rewardApprovalService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:dailyTraining')")
    @Log(title = "台账导入-日常培训记录", businessType = BusinessType.IMPORT)
    @PostMapping("/dailyTraining")
    public AjaxResult importDailyTraining(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerDailyTraining> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerDailyTraining.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        dailyTrainingService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:leaderDuty')")
    @Log(title = "台账导入-组长履职情况记录", businessType = BusinessType.IMPORT)
    @PostMapping("/leaderDuty")
    public AjaxResult importLeaderDuty(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerLeaderDuty> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerLeaderDuty.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        leaderDutyService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:healthSoldier')")
    @Log(title = "台账导入-健康锐兵", businessType = BusinessType.IMPORT)
    @PostMapping("/healthSoldier")
    public AjaxResult importHealthSoldier(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerHealthSoldier> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerHealthSoldier.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        healthSoldierService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:dormFireSafety')")
    @Log(title = "台账导入-宿舍消防安全专项自查", businessType = BusinessType.IMPORT)
    @PostMapping("/dormFireSafety")
    public AjaxResult importDormFireSafety(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerDormFireSafety> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerDormFireSafety.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        dormFireSafetyService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    @PreAuthorize("@ss.hasPermi('ledger:import:trainingIssue')")
    @Log(title = "台账导入-培训台账问题通报", businessType = BusinessType.IMPORT)
    @PostMapping("/trainingIssue")
    public AjaxResult importTrainingIssue(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerTrainingIssue> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerTrainingIssue.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        trainingIssueService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    /**
     * 部门奖惩记录表导入
     * LedgerRewardPenalty
     */
    @PreAuthorize("@ss.hasPermi('ledger:import:rewardPenalty')")
    @Log(title = "台账导入-部门奖惩记录表", businessType = BusinessType.IMPORT)
    @PostMapping("/rewardPenalty")
    public AjaxResult importRewardPenalty(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerRewardPenalty> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerRewardPenalty.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        rewardPenaltyService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    /**
     * 请休假记录（特殊）表导入
     * LedgerLeaveSpecial
     */
    @PreAuthorize("@ss.hasPermi('ledger:import:leaveSpecial')")
    @Log(title = "台账导入-请休假记录特殊", businessType = BusinessType.IMPORT)
    @PostMapping("/leaveSpecial")
    public AjaxResult importLeaveSpecial(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerLeaveSpecial> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerLeaveSpecial.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        leaveSpecialService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }

    /**
     * 锦旗及感谢信记录表导入
     * LedgerBannerLetter
     */
    @PreAuthorize("@ss.hasPermi('ledger:import:bannerLetter')")
    @Log(title = "台账导入-锦旗及感谢信", businessType = BusinessType.IMPORT)
    @PostMapping("/bannerLetter")
    public AjaxResult importBannerLetter(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        List<LedgerBannerLetter> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), LedgerBannerLetter.class,
                new SimpleListener<>(list)).headRowNumber(2).sheet().doRead();
        list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
        bannerLetterService.batchInsert(list);
        return AjaxResult.success("导入成功，共" + list.size() + "条");
    }


    /**
     * 一键全量导入 - 解析多Sheet合并Excel（旅检三部"三三"数字管理平台.xlsx）
     */
    @PreAuthorize("@ss.hasPermi('ledger:import:combined')")
    @Log(title = "台账导入-一键全量导入", businessType = BusinessType.IMPORT)
    @PostMapping("/combined")
    public AjaxResult importCombined(@RequestParam("file") MultipartFile file) throws Exception {
        String batchNo = generateBatchNo();
        Map<String, String> result = combinedImportService.importAll(file, batchNo, getUsername());
        return AjaxResult.success(result);
    }

    /**
     * 按导入时间范围清理全部台账数据（20张表 + 台账同步配分事项）
     */
    @PreAuthorize("@ss.hasPermi('ledger:clear:all')")
    @Log(title = "台账数据清理", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clear")
    public AjaxResult clearByTimeRange(
            @RequestParam String beginTime,
            @RequestParam String endTime) {
        if (beginTime == null || beginTime.isEmpty() || endTime == null || endTime.isEmpty()) {
            return AjaxResult.error("请选择清理时间范围");
        }
        //开始时间给
        beginTime = " " + beginTime + " 00:00:00";
        endTime = " " + endTime + " 23:59:59";
        Map<String, Integer> result = combinedImportService.clearByCreateTime(beginTime, endTime);
        int total = result.values().stream().mapToInt(Integer::intValue).sum();
        return AjaxResult.success("清理完成，共删除 " + total + " 条记录", result);
    }

    /**
     * 通用 EasyExcel 监听器 - 简单收集行到列表
     */
    private static class SimpleListener<T> extends AnalysisEventListener<T> {
        private final List<T> list;
        SimpleListener(List<T> list) { this.list = list; }

        @Override
        public void invoke(T data, AnalysisContext context) {
            list.add(data);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {}
    }
}