package cn.iocoder.yudao.module.pms.controller.admin.maintain;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.pms.controller.admin.failure.vo.IotFailureReportProcessVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainSaveVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.failure.IotFailureReportDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainBomDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.oa.IotOaPersonDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.maintain.IotMaintainMapper;
import cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant;
import cn.iocoder.yudao.module.pms.oa.CallBackOaVo;
import cn.iocoder.yudao.module.pms.service.IotDeviceService;
import cn.iocoder.yudao.module.pms.service.failure.IotFailureReportService;
import cn.iocoder.yudao.module.pms.service.maintain.IotMaintainBomService;
import cn.iocoder.yudao.module.pms.service.maintain.IotMaintainService;
import cn.iocoder.yudao.module.pms.service.maintain.material.IotMaintainMaterialService;
import cn.iocoder.yudao.module.supplier.dal.dataobject.product.SupplierDO;
import cn.iocoder.yudao.module.supplier.service.product.SupplierService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import com.alibaba.fastjson.JSON;
import com.xingyuv.captcha.util.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;


@Tag(name = "管理后台 - 维修工单")
@RestController
@RequestMapping("/rq/iot-maintain")
@Validated
public class IotMaintainController {

    @Resource
    private IotMaintainService iotMaintainService;
    @Autowired
    private IotMaintainMaterialService iotMaintainMaterialService;
    @Autowired
    private IotMaintainBomService iotMaintainBomService;
    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private AdminUserApi adminUserApi;
    @Autowired
    private IotFailureReportService iotFailureReportService;
    @Resource
    private DeptApi deptApi;
    @Autowired
    private DictDataService dictDataService;
    @Autowired
    private IotMaintainMapper iotMaintainMapper;
    @Autowired
    private IotDeviceMapper iotDeviceMapper;

    @PostMapping("/create")
    @Operation(summary = "创建维修工单")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:create')")
    public CommonResult<Long> createIotMaintain(@RequestBody IotMaintainSaveVO createReqVO) {
        return success(iotMaintainService.createIotMaintain(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新维修工单")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:update')")
    public CommonResult<Boolean> updateIotMaintain(@Valid @RequestBody IotMaintainSaveVO updateReqVO) {
        iotMaintainService.updateIotMaintain(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除维修工单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:delete')")
    public CommonResult<Boolean> deleteIotMaintain(@RequestParam("id") Long id) {
        iotMaintainService.deleteIotMaintain(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得维修工单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:query')")
    public CommonResult<IotMaintainRespVO> getIotMaintain(@RequestParam("id") Long id) {
        IotMaintainDO iotMaintain = iotMaintainService.getIotMaintain(id);
        if (Objects.isNull(iotMaintain)) {
            throw new ServiceException(ErrorCodeConstant.INSPECT_DEVICE_CHANGE);
        }
        IotDeviceDO iotDevice = iotDeviceService.getIotDevice(iotMaintain.getDeviceId());
        IotMaintainRespVO bean = BeanUtils.toBean(iotMaintain, IotMaintainRespVO.class);
        bean.setPics(JSON.parseArray(bean.getPic(), String.class));
        bean.setOutFiles(JSON.parseArray(bean.getOutFile(), String.class));
        if (Objects.nonNull(iotDevice)&&Objects.nonNull(iotDevice.getManufacturerId())) {
            SupplierDO supplierDO1 = supplierService.get(iotDevice.getManufacturerId());
            bean.setSupplierName(Objects.nonNull(supplierDO1)?supplierDO1.getName():"");
        }
        List<IotMaintainBomDO> listByMaintainId = iotMaintainBomService.getListByMaintainId(id);
        bean.setMaintainBomDOS(listByMaintainId);
        bean.setYfDeviceCode(iotDevice.getYfDeviceCode());
        bean.setDeviceCode(iotDevice.getDeviceCode());
        return success(bean);
    }

    @GetMapping("/page")
    @Operation(summary = "获得维修工单分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:query')")
    public CommonResult<PageResult<IotMaintainRespVO>> getIotMaintainPage(@Valid IotMaintainPageReqVO pageReqVO) {
        PageResult<IotMaintainDO> pageResult = iotMaintainService.getIotMaintainPage(pageReqVO);
        List<IotMaintainRespVO> collect = pageResult.getList().stream().map(e -> {
            IotMaintainRespVO iotMaintainRespVO = new IotMaintainRespVO();
            BeanUtils.copyProperties(e, iotMaintainRespVO);
            if (Objects.nonNull(e.getDeptId())) {
                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
                if (Objects.nonNull(dept)) {
                    iotMaintainRespVO.setDeptName(dept.getName());
                }
            }

            if (StringUtils.isNotBlank(e.getCreator())) {
                AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(e.getCreator()));
                if (Objects.nonNull(user)) {
                    iotMaintainRespVO.setCreateName(user.getNickname());
                }
            }
            if (e.getFailureCode().contains("GZRDLS")) {
                iotMaintainRespVO.setCompany("rd");
            } else {
                String deviceCompany = iotDeviceService.getDeviceCompany(e.getDeviceId());
                iotMaintainRespVO.setCompany(deviceCompany);
            }
            return iotMaintainRespVO;
        }).collect(Collectors.toList());
        return success(new PageResult<>(collect, pageResult.getTotal()));
//        return success(BeanUtils.toBean(pageResult, IotMaintainRespVO.class));
    }

    @GetMapping("/page/app")
    @Operation(summary = "获得维修工单分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:query')")
    public CommonResult<PageResult<IotMaintainRespVO>> getIotMaintainPageApp(@Valid IotMaintainPageReqVO pageReqVO) {
        PageResult<IotMaintainDO> pageResult = iotMaintainService.getIotMaintainPageApp(pageReqVO);
        return success(BeanUtils.toBean(pageResult, IotMaintainRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出维修工单 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotMaintainExcel(@Valid IotMaintainPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotMaintainDO> list = iotMaintainService.getIotMaintainPage(pageReqVO).getList();
        List<IotMaintainRespVO> bean = BeanUtils.toBean(list, IotMaintainRespVO.class);
        List<DictDataDO> failureStatus = dictDataService.getDictDataListByDictType("pms_failure_status");
        bean.forEach(e -> {
            failureStatus.stream().filter(f -> f.getValue().equals(e.getStatus())).findFirst().ifPresent(f -> {
                e.setStatus(f.getLabel());
            });
            if (Objects.nonNull(e.getIfStop())) {
                e.setStop(e.getIfStop()?"是":"否");
            }
            DeptRespDTO dept = deptApi.getDept(e.getDeptId());
            if (dept != null) {
                e.setDeptName(dept.getName());
            }
        });
        // 导出 Excel
        ExcelUtils.write(response, "维修工单.xls", "数据", IotMaintainRespVO.class,
                        BeanUtils.toBean(bean, IotMaintainRespVO.class));
    }


    @PutMapping("/process-info")
    @Operation(summary = "委外维修更新流程信息")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:update')")
    public CommonResult<Long> updateIotFailureReportProcess(@RequestParam("id")String id, @RequestParam("assigneeUserId") String assigneeUserId) {
        IotFailureReportProcessVO iotFailureReportProcessVO = new IotFailureReportProcessVO();
        iotFailureReportProcessVO.setId(id);
        iotFailureReportProcessVO.setAssigneeUserId(Long.valueOf(assigneeUserId));
        return success(iotMaintainService.updateMaintainProcess(iotFailureReportProcessVO));
    }

    @GetMapping("/maintain/users")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    public CommonResult<List<AdminUserRespDTO>> getMaintainUsers(Long userId, Long businessId) {
        if (Objects.isNull(userId)&&Objects.isNull(businessId)) {
            return success(new ArrayList<>());
        }
        AdminUserRespDTO user = adminUserApi.getUser(userId);
        List<AdminUserRespDTO> userListByDept = adminUserApi.getUserListByDept(user.getDeptId());
        IotFailureReportDO iotFailureReportDO = iotFailureReportService.getIotFailureReport(businessId);
        if (Objects.isNull(iotFailureReportDO)) {
            return success(userListByDept);
        }
        List<AdminUserRespDTO> userListByDeptId = adminUserApi.getUserListByDeptId(iotFailureReportDO.getDeptId());
        userListByDept.addAll(userListByDeptId);
        if (StringUtils.isNotBlank(iotFailureReportDO.getCreator())&&Objects.nonNull(iotFailureReportDO.getCreator())) {
            AdminUserRespDTO creator = adminUserApi.getUser(Long.valueOf(iotFailureReportDO.getCreator()));
            userListByDept.add(creator);
        }
        return success(userListByDept);

    }

    @GetMapping("/maintain/applyusers")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    public CommonResult<List<IotOaPersonDO>> getApplyUsers(@RequestParam("id") String id) {
        List<IotOaPersonDO> maintainPerson = iotMaintainService.getMaintainPerson(id);
        return success(maintainPerson);
    }
    @GetMapping("/maintain/project")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    public CommonResult<List<IotOaPersonDO>> getProjectUsers(@RequestParam("id") String id) {
        List<IotOaPersonDO> maintainPerson = iotMaintainService.getProjectPerson(id);
        return success(maintainPerson);
    }

    @PostMapping("/oa")
    @PreAuthorize("@ss.hasPermission('system:oa:query')")
    public CommonResult<String> getProjectUsers(@RequestBody CallBackOaVo callBackOaVo) {
        if (StringUtils.isBlank(callBackOaVo.getRequestId())||StringUtils.isBlank(callBackOaVo.getIfSuccess())||Objects.isNull(callBackOaVo.getMainData())){
            throw new ServiceException(new ErrorCode(200, "参数缺失"));
        }
        iotMaintainService.oaDeal(callBackOaVo);
        return success("成功");
    }

    @Data
    public static class MaintainMethod{
        private Long id;
        private String maintainMethod;
        private String methodDescription;
    }

    @PostMapping("/method")
    @PreAuthorize("@ss.hasPermission('rq:iot-maintain:update')")
    public CommonResult<String> maintainMethod(@RequestBody MaintainMethod maintainMethod) {
        if (Objects.isNull(maintainMethod) || Objects.isNull(maintainMethod.getId()) || StringUtils.isBlank(maintainMethod.getMaintainMethod())) {
            throw new ServiceException(new ErrorCode(200, "参数缺失"));
        }
        iotMaintainService.methodDeal(maintainMethod);
        return success("成功");
    }

    @GetMapping("/init-maintain")
    @PermitAll
    public void initMaintain() {
        List<IotMaintainDO> deviceId = iotMaintainMapper.selectList("device_id", 10001);
        deviceId.forEach(device -> {
            List<IotDeviceDO> iotDeviceDOS = iotDeviceMapper.selectList("yf_device_code", device.getDeviceCode());
            if (CollUtil.isNotEmpty(iotDeviceDOS)) {
                IotDeviceDO iotDeviceDO = iotDeviceDOS.get(0);
                device.setDeviceId(iotDeviceDO.getId());
                device.setDeptId(iotDeviceDO.getDeptId());
                device.setDeviceName(iotDeviceDO.getDeviceName());
                device.setFailureName(iotDeviceDO.getDeviceCode()+iotDeviceDO.getDeviceName()+ DateUtil.format(device.getMaintainStartTime(),"yyyyMMdd"));
//                iotMaintainMapper.updateById(device);
            }
        });
        iotMaintainMapper.updateBatch(deviceId);
    }
}
