package cn.iocoder.yudao.module.rescue.controller.admin;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.constant.UserConstants;
import cn.iocoder.yudao.module.rescue.core.controller.BaseController;
import cn.iocoder.yudao.module.rescue.domain.*;
import cn.iocoder.yudao.module.rescue.dto.DriverInfoDto;
import cn.iocoder.yudao.module.rescue.dto.SysDictData;
import cn.iocoder.yudao.module.rescue.service.IRescueDictStaffService;
import cn.iocoder.yudao.module.rescue.service.IRescueInfoDetailService;
import cn.iocoder.yudao.module.rescue.service.IRescueInfoService;
import cn.iocoder.yudao.module.rescue.service.IRescueOrderInfoService;
import cn.iocoder.yudao.module.rescue.utils.ExcelUtil;
import cn.iocoder.yudao.module.rescue.utils.StringUtils;
import cn.iocoder.yudao.module.rescue.vo.BuckleVO;
import cn.iocoder.yudao.module.rescue.vo.MoneyManagement;
import cn.iocoder.yudao.module.rescue.vo.ReturnCarVO;
import cn.iocoder.yudao.module.staff.entity.CompanyStaff;
import cn.iocoder.yudao.module.staff.service.CompanyStaffService;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.permission.dto.RoleReqDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;


@RestController
@RequestMapping("/system/rescueInfo")
public class RescueInfoSystem extends BaseController {
    @Resource
    private IRescueInfoService rescueInfoService;

    @Resource
    private DictDataApi dictDataApi;

    @Resource
    private IRescueOrderInfoService infoService;

    @Resource
    private IRescueInfoDetailService rescueInfoDetailService;

    @Resource
    private IRescueDictStaffService rescueDictStaffService;

    @Resource
    @Lazy
    private AdminUserApi adminUserApi;

    @Resource
    private CompanyStaffService staffService;

    @Resource
    private RoleApi roleApi;

    @Resource
    private PermissionApi permissionApi;

    /**
     * 新增【道路救援发起】
     */
    @PostMapping("/add")
    public CommonResult add(@RequestBody @Valid RescueInfo rescueInfo) {
        rescueInfoService.insertRescueInfo(rescueInfo);
        return CommonResult.ok();
    }

    /**
     * 新增【道路救援发起】
     */

    @PostMapping("/update")
    public CommonResult update(@RequestBody RescueInfo rescueInfo) {
        if (ObjectUtil.isNotEmpty(rescueInfo.getSetMoney())){
            RescueOrderInfo orderInfo = infoService.getById(rescueInfo.getRescueOrderId());
            if (ObjectUtil.isEmpty(orderInfo)){
                throw exception0(500, "订单未成单");
            }
            orderInfo.setSetMoney(rescueInfo.getSetMoney());
            infoService.updateById(orderInfo);
        }
        rescueInfoService.updateById(rescueInfo);
        return CommonResult.ok();
    }

    /**
     * 取消【道路救援】
     */

    @PostMapping("/cancel")
    public CommonResult cancel(Long id) {
        RescueInfo rescueInfo = new RescueInfo();
        rescueInfo.setId(id);
        rescueInfo.setRescueStatus("0");
        return CommonResult.success(rescueInfoService.updateRescueInfo(rescueInfo));
    }


    /**
     * 查询【请填写功能名称】列表
     */
    @GetMapping("/list")
    public CommonResult list(RescueInfo rescueInfo,
                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNum,
                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<RescueInfo> page = new Page<>(pageNum, pageSize);
        IPage<RescueInfo> rescueInfos = rescueInfoService.selectRescueListSystem(page,rescueInfo);
        return success(rescueInfos);
    }

    /**
     * 查询【请填写功能名称】列表
     */
    @GetMapping("/list2")
    public CommonResult<IPage<?>> list2(RescueInfo rescueInfo,
                                        @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                        @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<RescueInfo> page = new Page<>(pageNo, pageSize);
        IPage<RescueInfo> list = rescueInfoService.selectRescueListSystem2(rescueInfo, page);
        return success(list);
    }

    @GetMapping("/watchImg")
    public CommonResult watchImg(@RequestParam("rescueId") Long rescueId) {
        List<String> resList = new ArrayList<>();
        RescueInfoDetail rescueInfoDetail = new RescueInfoDetail();
        rescueInfoDetail.setRescueInfoId(rescueId);
        List<RescueInfoDetail> details = rescueInfoDetailService.selectRescueInfoDetailList(rescueInfoDetail);
        if (CollectionUtil.isNotEmpty(details)) {
            List<String> images = details.stream().filter(it -> {
                return StringUtils.isNotEmpty(it.getImages());
            }).map(RescueInfoDetail::getImages).collect(Collectors.toList());
            for (String image : images) {
                for (String s : image.split(",")) {
                    resList.add(s);
                }
            }
        }

        return CommonResult.success(resList);
    }

    /**
     * 导出【请填写功能名称】列表
     */
//    @PreAuthorize("@ss.hasPermission('system:info:export')")
    @GetMapping("/export")
    public void export(HttpServletResponse response, RescueInfo rescueInfo,
                       @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) throws Exception {
        List<RescueInfo> list = new ArrayList<>();
        while (true){
            Page<RescueInfo> page = new Page<>(pageNo, pageSize);
            IPage<RescueInfo> rescueInfoIPage = rescueInfoService.selectRescueListSystem2(rescueInfo, page);
            if (ObjectUtil.isNotEmpty(rescueInfoIPage) && !rescueInfoIPage.getRecords().isEmpty()){
                rescueInfoIPage.getRecords().forEach(item -> {
                    item.setSetMoneyYuan(Double.valueOf(Optional.ofNullable(item.getSetMoney()).orElse(0L)) / 100);
                    item.setPayMoneyYuan(Double.valueOf(Optional.ofNullable(item.getPayMoney()).orElse(0L)) / 100);
                });
                list.addAll(rescueInfoIPage.getRecords());
                pageNo++;
            }else {
                break;
            }
        }
        ExcelUtil<RescueInfo> util = new ExcelUtil<RescueInfo>(RescueInfo.class);
        util.exportExcel(response, list, "救援订单数据");
    }

    //指派司机
    @PostMapping("/designateDriver")
    public CommonResult designateDriver(Long rescueId, Long driverId) throws Exception {
        rescueInfoService.designateDriver(rescueId, driverId);
        return CommonResult.success("指派成功");
    }

    /**
     * 查询【请填写功能名称】列表
     */
    @GetMapping("/driverList")
    public CommonResult<IPage<?>> driverList(DriverInfoDto driverInfoDto,
                                             @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                             @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<DriverInfo> page = new Page<>(pageNo, pageSize);
        IPage<DriverInfo> list = rescueInfoService.driverList(driverInfoDto, page);
        return success(list);
    }

    @GetMapping("/getDriverById")
    public CommonResult getDriverById(Long driverId) {
        return CommonResult.success(rescueInfoService.getDriverById(driverId));
    }

    /**
     * 新增信息司机
     */
    @PostMapping("/addDriver")
    public CommonResult addDriver(@RequestBody DriverInfo driverInfo) {
        try {
            rescueInfoService.addDriver(driverInfo);
        } catch (Exception e) {
            return CommonResult.error(500, e.getMessage());
        }

        return CommonResult.success("新增成功");
    }

    /**
     * 修改信息司机
     */
    @PostMapping("/updateDriver")
    public CommonResult updateDriver(@RequestBody DriverInfo driverInfoDto) {
        rescueInfoService.updateDriver(driverInfoDto);
        return CommonResult.success("修改成功");
    }

    @PostMapping("/delDriver")
    public CommonResult delDriver(Long[] ids) {
        rescueInfoService.delDriver(ids);
        return CommonResult.success("删除成功");
    }

    //获取扣车地点
    @GetMapping("/getKcPosition")
    public CommonResult getKcPosition(@RequestParam(required = false) String searchValue) {
        //当前登录用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String dictStr = "kcPosition-" + loginUser.getTenantId();
        if (!dictDataApi.exist(dictStr)) {
            //初始化
            dictDataApi.createDictType("扣车地点-" + loginUser.getTenantId(), dictStr);
        }
        List<DictDataRespDTO> dataList = dictDataApi.getDictDataList(dictStr);
        if (CollectionUtil.isEmpty(dataList)) {
            dataList = new ArrayList<>();
        }
        if (StringUtils.isNotEmpty(searchValue)) {
            dataList = dataList.stream().filter(it -> {
                return it.getLabel().contains(searchValue);
            }).collect(Collectors.toList());
        }
        return CommonResult.success(dataList);
    }

    //新增扣车地点
    @PostMapping("/addKcPosition")
    public CommonResult addKcPosition(@RequestBody SysDictData dictData) {
        //当前登录用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String dictStr = "kcPosition-" + loginUser.getTenantId();
        dictDataApi.addDictData(dictStr, dictData.getDictLabel(), dictData.getDictValue(), dictData.getDictSort().intValue());
        return CommonResult.ok();
    }


    //删除扣车地点
    @PostMapping("/delKcPosition")
    public CommonResult delKcPosition(Long dictId) {
        dictDataApi.deleteDictDataByIds(new Long[]{dictId});
        return CommonResult.ok();
    }

    //轨迹计算
    @PostMapping("/trajectoryJs")
    public CommonResult trajectoryJs(Long rescueId) throws Exception {
        rescueInfoService.trajectoryJs(rescueId);
        return CommonResult.success("成功");
    }

    //轨迹计算
    @DeleteMapping("/{ids}")
    public CommonResult remove(@PathVariable Long[] ids) throws Exception {
        rescueInfoService.deleteRescueInfoByIds(ids);
        return CommonResult.success("成功");
    }


    //获取救援路段
    @GetMapping("/getRescueRoad")
    public CommonResult getRescueRoad(String searchValue) throws Exception {
        //当前登录用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String dictStr = "kcRescueRoad-" + loginUser.getTenantId();
        if (!dictDataApi.exist(dictStr)) {
            //初始化
            dictDataApi.createDictType("道路救援路段-" + loginUser.getTenantId(), dictStr);
        }
        List<DictDataRespDTO> dataList = dictDataApi.getDictDataList(dictStr);
        if (CollectionUtil.isEmpty(dataList)) {
            dataList = new ArrayList<>();
        }
        if (StringUtils.isNotEmpty(searchValue)) {
            dataList = dataList.stream().filter(it -> {
                return it.getLabel().contains(searchValue);
            }).collect(Collectors.toList());
        }
        return CommonResult.success(dataList);
    }

    //新增救援路段
    @PostMapping("/addRescueRoad")
    public CommonResult addRescueRoad(@RequestBody SysDictData dictData) throws Exception {
        //当前登录用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String dictStr = "kcRescueRoad-" + loginUser.getTenantId();
        dictDataApi.addDictData(dictStr, dictData.getDictLabel(), dictData.getDictValue(), dictData.getDictSort().intValue());
        return CommonResult.ok();
    }

    //删除救援路段
    @PostMapping("/delRescueRoad")
    public CommonResult delRescueRoad(Long dictId) {
        dictDataApi.deleteDictDataByIds(new Long[]{dictId});
        RescueDictStaff flag = rescueDictStaffService.getOne(new LambdaQueryWrapper<RescueDictStaff>().eq(RescueDictStaff::getDictId, dictId));
        if (ObjectUtil.isNotEmpty(flag)){
            rescueDictStaffService.remove(new LambdaQueryWrapper<RescueDictStaff>().eq(RescueDictStaff::getDictId, dictId));
        }
        return CommonResult.ok();
    }

    /**
     * moneyManagement
     */
    @GetMapping("/moneyManagement")
    public CommonResult moneyManagement(RescueInfo rescueInfo,
                                        @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                        @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<RescueInfo> page = new Page<>(pageNo, pageSize);
        IPage<RescueInfo> rescueInfos = rescueInfoService.getRescueInfoByDriver(rescueInfo, page);
        List<MoneyManagement> list = rescueInfoService.moneyManagement2(rescueInfos.getRecords(), rescueInfo.getRescueStart());
        IPage<MoneyManagement> result = new Page<>(pageNo, pageSize);
        result.setRecords(list);
        result.setTotal(rescueInfos.getTotal());
        result.setCurrent(rescueInfos.getCurrent());
        result.setPages(rescueInfos.getPages());
        result.setSize(rescueInfos.getSize());
        return success(result);
    }

    /**
     * moneyManagement
     */
    @GetMapping("/moneyManagementData")
    public CommonResult moneyManagementData(RescueInfo rescueInfo) {
        JSONObject res = rescueInfoService.listData(rescueInfo);
        return CommonResult.success(res);
    }

    /** TODO 有问题，处理时间太长，还会报错 */
    @GetMapping("/exportManagement")
    public void exportManagement(HttpServletResponse response, RescueInfo rescueInfo,
                                 @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                 @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        List<MoneyManagement> result = new ArrayList<>();
        while (true){
            Page<RescueInfo> page = new Page<>(pageNo, pageSize);
            IPage<RescueInfo> rescueInfos = rescueInfoService.getRescueInfoByDriver(rescueInfo, page);
            if (ObjectUtil.isEmpty(rescueInfos) || rescueInfos.getRecords().isEmpty()){
                break;
            }
            List<MoneyManagement> list = rescueInfoService.moneyManagement2(rescueInfos.getRecords(), rescueInfo.getRescueStart());
            result.addAll(list);
            pageNo ++;
        }
        JSONObject jsonObject = rescueInfoService.listData(rescueInfo);
        ExcelUtil<MoneyManagement> util = new ExcelUtil<MoneyManagement>(MoneyManagement.class);
        String title = "施救总金额：" + jsonObject.getString("allMoney") + "元 出车次数：" + jsonObject.getString("allNum") + "次 提成总金额：" + jsonObject.getString("tcAll") + " 元 燃油费小计：" + jsonObject.getString("refuelMoney") + "元";
        util.exportExcel(response, result, "救援财务报表", title);
    }

    /**
     * 查询救援路段的司机和管理人员信息
     * @author 小李
     * @date 9:17 2024/8/26
     * @param ids 路段IDs 一个或多个
     **/
    @GetMapping("/getDictStaff/{ids}")
    public CommonResult getDictStaff(@PathVariable("ids") Long[] ids){
        List<Long> dictIds = Arrays.asList(ids);
        List<RescueDictStaff> rescueDictStaffs = dictIds.stream().map(item -> {
            RescueDictStaff rescueDictStaff = rescueDictStaffService.getOne(new LambdaQueryWrapper<RescueDictStaff>().eq(RescueDictStaff::getDictId, item));
            if (ObjectUtil.isNotEmpty(rescueDictStaff)) {
                // 拿路段管理员的名字
                AdminUserRespDTO user = adminUserApi.getUser(rescueDictStaff.getManageId());
                rescueDictStaff.setManageName(user.getNickname());
                // 拿路段司机的名字
                List<Long> driverIds = Arrays.asList(rescueDictStaff.getDriverIds().split(",")).stream().map(Long::parseLong).collect(Collectors.toList());
                List<AdminUserRespDTO> drivers = adminUserApi.getUserList(driverIds);
                StringJoiner tempStr = new StringJoiner("|");
                for (AdminUserRespDTO driver : drivers) {
                    tempStr.add(driver.getNickname());
                }
                rescueDictStaff.setDriverNames(tempStr.toString());
            }
            return rescueDictStaff;
        }).collect(Collectors.toList());
        return success(rescueDictStaffs);
    }

    /**
     * 获得所有救援业务管理员
     * @author 小李
     * @date 10:10 2024/8/26
     **/
    @GetMapping("/getManages")
    public CommonResult getManages(){
        RoleReqDTO roleInfo = roleApi.getRoleInfo(UserConstants.RESCUE_MANAGE);
        List<Long> userIds = permissionApi.getUserIdByRoleId(roleInfo.getId());
        List<CompanyStaff> staffs = staffService.list(new LambdaQueryWrapper<CompanyStaff>().in(CompanyStaff::getUserId, userIds));
        return success(staffs);
    }

    /**
     * 获得所有司机
     * @author 小李
     * @date 10:10 2024/8/26
     **/
    @GetMapping("/getDrivers")
    public CommonResult getDrivers(){
        RoleReqDTO roleInfo = roleApi.getRoleInfo(UserConstants.RESCUE_DRIVER);
        List<Long> userIds = permissionApi.getUserIdByRoleId(roleInfo.getId());
        List<CompanyStaff> staffs = staffService.list(new LambdaQueryWrapper<CompanyStaff>().in(CompanyStaff::getUserId, userIds));
        return success(staffs);
    }

    @PostMapping("/bindDictStaff")
    public CommonResult bindDictStaff(@RequestBody RescueDictStaff rescueDictStaff){
        rescueDictStaffService.saveOrUpdate(rescueDictStaff);
        return CommonResult.ok();
    }

    /**
     * 获取扣车单位和具体数量
     * @author 小李
     * @date 10:46 2024/9/5
    **/
    @GetMapping("/buckle")
    public CommonResult listBuckle(){
        return success(rescueInfoService.listBuckle());
    }

    /**
     * 查看单个扣车单位信息
     * @author 小李
     * @date 11:44 2024/9/6
     * @param id 部门ID
    **/
    @GetMapping("/buckle/{id}")
    public CommonResult getBuckle(@PathVariable("id") Long id){
        return success(rescueInfoService.getBuckle(id));
    }

    /**
     * 还车方法
     * @author 小李
     * @date 14:48 2024/9/6
     * @param returnCarVO 订单信息
    **/
    @PostMapping("/returnCar")
    public CommonResult returnCar(@RequestBody ReturnCarVO returnCarVO){
        rescueInfoService.returnCar(returnCarVO);
        return CommonResult.ok();
    }

    /**
     * 入库方法
     * @author 小李
     * @date 10:37 2024/9/7
     * @param returnCarVO 订单信息
    **/
    @PostMapping("/inBase")
    public CommonResult inBase(@RequestBody ReturnCarVO returnCarVO){
        rescueInfoService.inBase(returnCarVO);
        return CommonResult.ok();
    }
}
