package com.ruoyi.business.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AddTreeSelect;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.database.domain.*;
import com.ruoyi.database.domain.dto.ApprovaltDto;
import com.ruoyi.database.service.ApprovalProcessService;
import com.ruoyi.database.service.BaseAddressInfoService;
import com.ruoyi.database.service.BusinessTripApprovalService;
import com.ruoyi.database.service.gwglLogService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description BusinessTripApprovalController
 * @Author lijingtong
 * @Date 2025-05-29
 */

@RestController
@RequestMapping("/BusinessTripApproval")
@RequiredArgsConstructor
@Api(tags = "出差审批单")
public class BusinessTripApprovalController extends BaseController {

    private final BusinessTripApprovalService businessTripApprovalService;
    private final ISysUserService sysUserService;
    private final ISysDeptService sysDeptService;
    private final BaseAddressInfoService baseAddressInfoService;
    private final ApprovalProcessService approvalsProcessService;
    private final gwglLogService gwglLogService;


    @PostMapping("/list")
    @ApiOperation("查询出差申请")
    public TableDataInfo list(BusinessTripApproval businessTripApproval) {
        startPage();
        QueryWrapper<BusinessTripApproval> queryWrapper = new QueryWrapper<>(businessTripApproval);
        queryWrapper.orderByDesc("create_time");
        List<BusinessTripApproval> list = businessTripApprovalService.list(queryWrapper);
        long size = businessTripApprovalService.count(queryWrapper);
        return getDataTableEnhance(list, size);
    }


    @PostMapping("/add")
    @ApiOperation("新增出差申请")
    public AjaxResult add(@RequestBody BusinessTripApproval dto) {
        SysUser user = getLoginUser().getUser();
        if (dto.getHasOffcialCar() != null && dto.getHasOffcialCar() == 1) {
            if (dto.getCarModel() == null) {
                throw new RuntimeException("请选择使用车型");
            }
            if (dto.getUseCarType() == null) {
                throw new RuntimeException("请选择用车方式");
            }
            if (dto.getSeats() == null) {
                throw new RuntimeException("请输入座位数");
            }
        }
        if (dto.getStartDate() == null || dto.getEndDate() == null) {
            throw new RuntimeException("请选择出差时间范围");
        }
        if (dto.getDestinationId() == null) {
            throw new RuntimeException("请选择出差目的地");
        }
        dto.setUserName(user.getNickName());
        dto.setUserId(user.getUserId());
        dto.setDepartment(user.getDept().getDeptName());
        List<Long> togUserIdList = dto.getTogUserIdList();
        StringBuilder ids = new StringBuilder();
        if (togUserIdList != null && !togUserIdList.isEmpty()) {
            for (Long aLong : togUserIdList) {
                if (ids.length() > 0) {
                    ids.append(",");
                }
                ids.append(aLong);
            }
            dto.setTogUserIds(ids.toString());
        }

        String s = OrderNumberGenerator();
        dto.setApplyNo(s);
        UUID uuid = UUID.randomUUID();
        String uuids = uuid.toString();

        dto.setUuid(uuids);
        BaseAddressInfo byId = baseAddressInfoService.getById(dto.getDestinationId());
        ApprovalProcess approvalProcess = new ApprovalProcess();
        approvalProcess.setApprovalNo(s);
        approvalProcess.setProcessTitle("出差呈请");
        approvalProcess.setSubmitterName(user.getNickName());
        approvalProcess.setSubmitterId(user.getUserId());
        approvalProcess.setSubmitTime(new Date().getTime());
        approvalProcess.setMatterType(2);
        approvalProcess.setApprovalStatus(0);
        approvalProcess.setReadStatus(0);
        approvalProcess.setBusinessTripDestination(byId.getAddName());
        approvalProcess.setStartTime(dto.getStartDate());
        approvalProcess.setEndTime(dto.getEndDate());
        approvalProcess.setCreateTime(new Date().getTime());
        approvalProcess.setUuid(uuids);
        approvalsProcessService.save(approvalProcess);
        return toAjax(businessTripApprovalService.save(dto));
    }


    @GetMapping("/userList")
    @ApiOperation("查询用户人员列表")
    public AjaxResult applyList() {
        List<SysUser> sysUsers = sysUserService.selectList();
        List<SysDept> sysDepts = sysDeptService.selectDeptList(new SysDept());
        sysDepts = sysDepts.stream()
                .filter(dept -> dept.getDeptId() != 131000) // 过滤掉id为131000的部门
                .collect(Collectors.toList());
        List<SysDept> depts = sysDeptService.buildDeptTree(sysDepts);
        Map<Long, List<SysUser>> deptUsersMap = new HashMap<>();
        for (SysUser user : sysUsers) {
            deptUsersMap.computeIfAbsent(user.getDeptId(), k -> new ArrayList<>()).add(user);
        }
        return AjaxResult.success(buildTree(depts, deptUsersMap));
    }


    public List<TreeSelect> buildTree(List<SysDept> depts, Map<Long, List<SysUser>> deptUsersMap) {
        List<TreeSelect> treeList = new ArrayList<>();
        for (SysDept dept : depts) {
            TreeSelect treeSelect = new TreeSelect();
            treeSelect.setId(dept.getDeptId());
            treeSelect.setLabel(dept.getDeptName());
            // 分配用户到部门
            List<SysUser> users = deptUsersMap.getOrDefault(dept.getDeptId(), Collections.emptyList());
            // 这里可以根据需要处理用户信息，比如只存储用户名或创建包含用户详细信息的子对象
            // 这里简单示例，只存储用户名列表
            List<TreeSelect> children = new ArrayList<>();
            if (users != null) {
                for (SysUser sysUser : users) {
                    TreeSelect treeSelect1 = new TreeSelect();
                    treeSelect1.setLabel(sysUser.getNickName());
                    treeSelect1.setId(sysUser.getUserId());
                    treeSelect1.setDictId(dept.getDeptId());
                    treeSelect1.setDictName(dept.getDeptName());
                    children.add(treeSelect1);
                }
            }
            // 递归处理子部门
            children.addAll(buildTree(dept.getChildren(), deptUsersMap));
            if (!children.isEmpty()) {
                treeSelect.setChildren(children); // 注意：这里我们重置了children，因为前面我们错误地将它设置为了用户名字符串列表
            }

            treeList.add(treeSelect);
        }
        return treeList;
    }


    @GetMapping("/addressList")
    @ApiOperation("查询地址信息列表")
    public AjaxResult addressList() {
        List<BaseAddressInfo> allAddresses = baseAddressInfoService.list();
        Map<Long, List<BaseAddressInfo>> addressMap = allAddresses.stream()
                .collect(Collectors.groupingBy(BaseAddressInfo::getTopId));
        List<AddTreeSelect> tree = buildTree(addressMap, 0L);
        return AjaxResult.success(tree);
    }

    private List<AddTreeSelect> buildTree(
            Map<Long, List<BaseAddressInfo>> addressMap,
            Long parentId
    ) {
        List<BaseAddressInfo> children = addressMap.get(parentId);
        if (children == null) return Collections.emptyList();

        return children.stream()
                .map(info -> {
                    AddTreeSelect node = new AddTreeSelect();
                    node.setId(info.getId());
                    node.setLabel(info.getAddName());
                    node.setValue(info.getId().toString());
                    node.setChildren(buildTree(addressMap, info.getId()));
                    return node;
                })
                .collect(Collectors.toList());
    }
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    private static final String DATA_KEY = "DDATAKEY:";

    public static String OrderNumberGenerator() {
        String format = sdf.format(new Date());
        RedisCache bean = SpringUtils.getBean(RedisCache.class);
        bean.setCacheObject(DATA_KEY + format, bean.getCacheObject(DATA_KEY + format) == null ? 1 : (Integer) (bean.getCacheObject(DATA_KEY + format)) + 1);
        return format + String.format("%04d", (Integer) (bean.getCacheObject(DATA_KEY + format)));
    }


    @ApiOperation("审批出差申请")
    @PostMapping("/approval")
    public AjaxResult approval(ApprovaltDto dto) {
        SysUser user = getLoginUser().getUser();
        Long id = dto.getId();
        Integer state = dto.getState();
        BusinessTripApproval businessTripApproval = businessTripApprovalService.getById(id);
        businessTripApproval.setState(state);
        boolean result = businessTripApprovalService.updateById(businessTripApproval);
        gwglLog gwglLog = new gwglLog();
        gwglLog.setApplyNo(businessTripApproval.getApplyNo());
        gwglLog.setDeptName(businessTripApproval.getDepartment());
        gwglLog.setUserId(businessTripApproval.getUserId());
        gwglLog.setUserName(businessTripApproval.getUserName());
//        gwglLog.setCreateTime(businessTripApproval.getCreateTime());
        gwglLog.setReason(businessTripApproval.getReason());
        gwglLog.setType(1);
        gwglLog.setApplyNo(businessTripApproval.getApplyNo());
        gwglLog.setChecker(user.getNickName());
        gwglLog.setCheckTime(LocalDateTime.now());
        gwglLog.setCheckState(state);
        boolean result1 = gwglLogService.save(gwglLog);
        if (!result || !result1) {
            return AjaxResult.error("审批出差申请失败");
        }
        return AjaxResult.success("审批出差申请成功");
    }

}
