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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.attendance.domain.AttendanceRecord;
import com.sundot.airport.attendance.dto.AttendanceRecordImportVO;
import com.sundot.airport.attendance.service.IAttendanceRecordService;
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.core.page.TableDataInfo;
import com.sundot.airport.common.dto.UserInfo;
import com.sundot.airport.common.enums.BusinessType;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.poi.ExcelUtil;
import com.sundot.airport.web.core.utils.DataPermissionUtils;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.web.core.cache.UserCache;
import com.sundot.airport.common.core.domain.DataPermissionResult;
import com.sundot.airport.common.enums.DataPermissionType;
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 javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 考勤记录Controller
 *
 * @author wangchong
 * @date 2025-07-10
 */
@RestController
@RequestMapping("/attendance/attendanceRecord")
public class AttendanceRecordController extends BaseController {
    @Autowired
    private IAttendanceRecordService attendanceRecordService;

    @Autowired
    private UserCache userCache;

    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 查询考勤记录列表
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:list')")
    @GetMapping("/list")
    public TableDataInfo list(AttendanceRecord attendanceRecord) {
        // 应用数据权限过滤
        DataPermissionResult dataPermission = DataPermissionUtils.getDataPermission(getUserId(), getDeptId(), getLoginUser());
        switch (dataPermission.getPermissionType()) {
            case SELF:
                attendanceRecord.setUserId(dataPermission.getValue());
                break;
            case STATION:
                attendanceRecord.setStationCode(dataPermission.getValue().toString());
                break;
            case BRIGADE:
                attendanceRecord.setBrigadeCode(dataPermission.getValue().toString());
                break;
            case DEPARTMENT:
                attendanceRecord.setDepartmentCode(dataPermission.getValue().toString());
                break;
            case TEAM:
                attendanceRecord.setTeamCode(dataPermission.getValue().toString());
                break;
            case ALL:
            default:
                // 不设置过滤条件，查看所有数据
                break;
        }

        startPage();
        List<AttendanceRecord> list = attendanceRecordService.selectAttendanceRecordList(attendanceRecord);
        return getDataTable(list);
    }

    /**
     * 导出考勤记录列表
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:export')")
    @Log(title = "考勤记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AttendanceRecord attendanceRecord) {
        // 应用数据权限过滤
        DataPermissionResult dataPermission = DataPermissionUtils.getDataPermission(getUserId(), getDeptId(), getLoginUser());
        switch (dataPermission.getPermissionType()) {
            case SELF:
                attendanceRecord.setUserId(dataPermission.getValue());
                break;
            case STATION:
                attendanceRecord.setStationCode(dataPermission.getValue().toString());
                break;
            case BRIGADE:
                attendanceRecord.setBrigadeCode(dataPermission.getValue().toString());
                break;
            case DEPARTMENT:
                attendanceRecord.setDepartmentCode(dataPermission.getValue().toString());
                break;
            case TEAM:
                attendanceRecord.setTeamCode(dataPermission.getValue().toString());
                break;
            case ALL:
            default:
                // 不设置过滤条件，查看所有数据
                break;
        }

        List<AttendanceRecord> list = attendanceRecordService.selectAttendanceRecordList(attendanceRecord);
        ExcelUtil<AttendanceRecord> util = new ExcelUtil<AttendanceRecord>(AttendanceRecord.class);
        util.exportExcel(response, list, "考勤记录数据");
    }

    /**
     * 获取考勤记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(attendanceRecordService.selectAttendanceRecordById(id));
    }

    /**
     * 新增考勤记录
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:add')")
    @Log(title = "考勤记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AttendanceRecord attendanceRecord) {
        UserInfo userInfo = userCache.getUserInfo(attendanceRecord.getUserId());
        if (Objects.nonNull(userInfo.getTeamsId())) {
            attendanceRecord.setTeamCode(userInfo.getTeamsId().toString());
        }
        attendanceRecord.setTeamName(userInfo.getTeamsName());
        if (Objects.nonNull(userInfo.getDepartmentId())) {
            attendanceRecord.setDepartmentCode(userInfo.getDepartmentId().toString());
        }
        attendanceRecord.setDepartmentName(userInfo.getDepartmentName());
        if (Objects.nonNull(userInfo.getBrigadeId())) {
            attendanceRecord.setBrigadeCode(userInfo.getBrigadeId().toString());
        }
        attendanceRecord.setBrigadeName(userInfo.getBrigadeName());
        if (Objects.nonNull(userInfo.getStationId())) {
            attendanceRecord.setStationCode(userInfo.getStationId().toString());
        }
        attendanceRecord.setStationName(userInfo.getStationName());
        attendanceRecord.setUserName(userInfo.getNickName());
        attendanceRecord.setRevision(1L);
        attendanceRecord.setWorkDuration((attendanceRecord.getCheckOutTime().getTime() - attendanceRecord.getCheckInTime().getTime()) / 1000 / 60);
        attendanceRecord.setAttendanceDate(DateUtil.date(attendanceRecord.getCheckInTime()));
        attendanceRecord.setOverDuration(0L);
        attendanceRecord.setCreateBy(getUserId().toString());
        return toAjax(attendanceRecordService.insertAttendanceRecord(attendanceRecord));
    }

    /**
     * 修改考勤记录
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:edit')")
    @Log(title = "考勤记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AttendanceRecord attendanceRecord) {
        attendanceRecord.setUpdateBy(getUserId().toString());
        attendanceRecord.setRevision(attendanceRecord.getRevision() + 1);
        attendanceRecord.setWorkDuration((attendanceRecord.getCheckOutTime().getTime() - attendanceRecord.getCheckInTime().getTime()) / 1000 / 60);
        attendanceRecord.setAttendanceDate(DateUtil.date(attendanceRecord.getCheckInTime()));
        return toAjax(attendanceRecordService.updateAttendanceRecord(attendanceRecord));
    }

    /**
     * 删除考勤记录
     */
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:remove')")
    @Log(title = "考勤记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(attendanceRecordService.deleteAttendanceRecordByIds(ids));
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<AttendanceRecordImportVO> util = new ExcelUtil<AttendanceRecordImportVO>(AttendanceRecordImportVO.class);
        util.importTemplateExcel(response, "用户数据");
    }

    @Log(title = "考勤管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('attendance:attendanceRecord:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
        ExcelUtil<AttendanceRecordImportVO> util = new ExcelUtil<AttendanceRecordImportVO>(AttendanceRecordImportVO.class);
        List<AttendanceRecordImportVO> list = util.importExcel(file.getInputStream());
        if (CollectionUtil.isEmpty(list)) {
            throw new ServiceException("导入用户数据不能为空");
        }
        validateData(list);
        String message = importData(list);
        return success(message);
    }

    private void validateData(List<AttendanceRecordImportVO> list) {
        StringBuilder failureMsg = new StringBuilder();
        int failureNum = 2;
        for (AttendanceRecordImportVO vo : list) {
            if (StrUtil.isBlank(vo.getUserName())) {
                failureMsg.append("<br/>第 ").append(failureNum).append(" 行用户姓名不能为空");
            }
            UserInfo userInfo = userCache.getUserInfo(vo.getUserName());
            if (Objects.isNull(userInfo) || Objects.isNull(userInfo.getUserId())) {
                failureMsg.append("<br/>第 ").append(failureNum).append(" 行用户不存在");
            }
            if (ObjUtil.isNull(vo.getAttendanceDate())) {
                failureMsg.append("<br/>第 ").append(failureNum).append(" 行考勤日期格式错误或者不能为空");
            }
            if (ObjUtil.isNull(vo.getCheckInTime())) {
                failureMsg.append("<br/>第 ").append(failureNum).append(" 行签到时间格式错误或者不能为空");
            }
            if (ObjUtil.isNull(vo.getCheckOutTime())) {
                failureMsg.append("<br/>第 ").append(failureNum).append(" 行签退时间格式错误或者不能为空");
            }
            failureNum++;
        }
        if (StrUtil.isNotBlank(failureMsg)) {
            throw new ServiceException(failureMsg.toString());
        }
    }

    private String importData(List<AttendanceRecordImportVO> list) {
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (AttendanceRecordImportVO vo : list) {
            UserInfo userInfo = userCache.getUserInfo(vo.getUserName());
            try {
                AttendanceRecord attendanceRecord = new AttendanceRecord();
                attendanceRecord.setRevision(1L);
                attendanceRecord.setUserId(userInfo.getUserId());
                attendanceRecord.setCheckInTime(vo.getCheckInTime());
                attendanceRecord.setCheckOutTime(vo.getCheckOutTime());
                attendanceRecord.setWorkDuration((attendanceRecord.getCheckOutTime().getTime() - attendanceRecord.getCheckInTime().getTime()) / 1000 / 60);
                if (Objects.nonNull(userInfo.getTeamsId())) {
                    attendanceRecord.setTeamCode(userInfo.getTeamsId().toString());
                }
                attendanceRecord.setTeamName(userInfo.getTeamsName());
                if (Objects.nonNull(userInfo.getDepartmentId())) {
                    attendanceRecord.setDepartmentCode(userInfo.getDepartmentId().toString());
                }
                attendanceRecord.setDepartmentName(userInfo.getDepartmentName());
                if (Objects.nonNull(userInfo.getBrigadeId())) {
                    attendanceRecord.setBrigadeCode(userInfo.getBrigadeId().toString());
                }
                attendanceRecord.setBrigadeName(userInfo.getBrigadeName());
                if (Objects.nonNull(userInfo.getStationId())) {
                    attendanceRecord.setStationCode(userInfo.getStationId().toString());
                }
                attendanceRecord.setStationName(userInfo.getStationName());
                attendanceRecord.setUserName(userInfo.getNickName());
                attendanceRecord.setRemark(vo.getRemark());
                attendanceRecord.setAttendanceDate(vo.getAttendanceDate());
                attendanceRecord.setOverDuration(0L);
                attendanceRecord.setCreateBy(getUserId().toString());
                attendanceRecord.setCreateTime(new Date());
                attendanceRecordService.insertAttendanceRecord(attendanceRecord);
                successNum++;
                successMsg.append("<br/>" + successNum + "、账号 " + userInfo.getUserName() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + userInfo.getUserName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}