package com.fuyuanshen.equipment.controller;


import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fuyuanshen.common.core.constant.ResponseMessageConstants;
import com.fuyuanshen.common.core.domain.ResponseVO;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.utils.file.FileUtil;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.customer.mapper.CustomerMapper;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.dto.DeviceExcelImportDTO;
import com.fuyuanshen.equipment.domain.dto.ImportResult;
import com.fuyuanshen.equipment.domain.form.DeviceForm;
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
import com.fuyuanshen.equipment.domain.vo.CustomerVo;
import com.fuyuanshen.equipment.excel.DeviceImportParams;
import com.fuyuanshen.equipment.excel.UploadDeviceDataListener;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.equipment.service.DeviceService;
import com.fuyuanshen.equipment.service.DeviceTypeService;
import com.fuyuanshen.equipment.service.impl.DeviceExportService;
import com.fuyuanshen.system.service.ISysOssService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.undertow.util.BadRequestException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * @Description:
 * @Author: WY
 * @Date: 2025/5/16
 **/
@Slf4j
@Tag(name = "web:设备管理", description = "web:设备管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/device")
public class DeviceController {

    private final ISysOssService ossService;
    private final DeviceService deviceService;
    private final DeviceMapper deviceMapper;
    private final CustomerMapper customerMapper;
    private final DeviceTypeService deviceTypeService;
    private final DeviceTypeMapper deviceTypeMapper;

    private final DeviceExportService exportService;


    @Operation(summary = "分页查询设备列表", security = {@SecurityRequirement(name = "bearer-key")})
    @GetMapping
    public TableDataInfo<Device> queryDevice(DeviceQueryCriteria criteria) throws IOException {
        Page<Device> page = new Page<>(criteria.getPageNum(), criteria.getPageSize());
        return deviceService.queryAll(criteria, page);
    }


    // @Log("新增设备")
    @Operation(summary = "新增设备")
    @PostMapping(value = "/add")
    public ResponseVO<Object> addDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
        try {
            deviceService.addDevice(deviceForm);
        } catch (Exception e) {
            log.error("addDevice error: " + e.getMessage());
            return ResponseVO.fail(e.getMessage());
        }
        return ResponseVO.success(null);
    }


    // @Log("修改设备")
    @Operation(summary = "修改设备")
    @PutMapping(value = "/update")
    public ResponseVO<Object> updateDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
        try {
            deviceService.update(deviceForm);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("updateDevice error: " + e.getMessage());
            return ResponseVO.fail("出错了");
        }
        return ResponseVO.success(null);
    }


    @Operation(summary = "设备详情")
    @GetMapping(value = "/detail/{id}")
    public ResponseVO<Object> getDevice(@PathVariable Long id) {
        Device device = deviceService.getById(id);
        return ResponseVO.success(device);
    }


    // @Log("删除设备")
    @Operation(summary = "删除设备")
    @DeleteMapping(value = "/delete")
    public ResponseVO<Object> deleteDevice(@Parameter(name = "传ID数组[]") @RequestBody List<Long> ids) {
        deviceService.deleteAll(ids);
        return ResponseVO.success(ResponseMessageConstants.DELETE_SUCCESS);
    }


    @Operation(summary = "设备定位")
    @GetMapping(value = "/locateDevice")
    public ResponseVO<Object> locateDevice(DeviceQueryCriteria criteria) throws IOException {
        List<Device> devices = deviceService.queryAllDevices(criteria);
        return ResponseVO.success(devices);
    }


    // @Log("分配客户")
    @Operation(summary = "分配客户")
    @PutMapping(value = "/assignCustomer")
    public ResponseVO<Object> assignCustomer(@Validated @RequestBody CustomerVo customerVo) {
        deviceService.assignCustomer(customerVo);
        return ResponseVO.success(null);
    }


    // @Log("撤回设备")
    @Operation(summary = "撤回分配设备")
    @PostMapping(value = "/withdraw")
    public ResponseVO<Object> withdrawDevice(@RequestBody List<Long> ids) {
        try {
            deviceService.withdrawDevice(ids);
        } catch (Exception e) {
            log.error("updateDevice error: " + e.getMessage());
            return ResponseVO.fail("出错了");
        }
        return ResponseVO.success(null);
    }


    /**
     * @param deviceForm
     * @return
     * @ModelAttribute 主要用于将请求参数绑定到 Java 对象上，它会从 HTTP 请求的查询参数（Query Parameters）
     * 或表单数据（Form Data）中提取值，并自动填充到指定的对象属性中。
     */
    // @Log("解绑设备")
    @Operation(summary = "解绑设备")
    @PostMapping(value = "/unbind")
    public ResponseVO<Object> unbindDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
        deviceService.unbindDevice(deviceForm);
        return ResponseVO.success("解绑成功！！！");
    }


    @Operation(summary = "导出数据设备")
    @GetMapping(value = "/download")
    public void exportDevice(HttpServletResponse response, DeviceQueryCriteria criteria) throws IOException {
        List<Device> devices = deviceService.queryAll(criteria);
        exportService.export(devices, response);
    }


    @Operation(summary = "导入设备数据")
    @PostMapping(value = "/import", consumes = "multipart/form-data")
    public ResponseVO<ImportResult> importData(@Parameter(name = "文件", required = true) @RequestPart("file") MultipartFile file) throws BadRequestException {

        String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
        if (!("xlsx".equalsIgnoreCase(suffix))) {
            throw new BadRequestException("只能上传Excel——xlsx格式文件");
        }

        ImportResult result = new ImportResult();
        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
            DeviceImportParams params = DeviceImportParams.builder().ossService(ossService)
                    .deviceService(deviceService).tenantId(loginUser.getTenantId())
                    .file(file).filePath("").deviceMapper(deviceMapper).deviceTypeService(deviceTypeService)
                    .deviceTypeMapper(deviceTypeMapper).userId(loginUser.getUserId())
                    .customerMapper(customerMapper).build();
            // 创建监听器
            UploadDeviceDataListener listener = new UploadDeviceDataListener(params);
            // 读取Excel
            EasyExcel.read(file.getInputStream(), DeviceExcelImportDTO.class, listener).sheet().doRead();
            // 获取导入结果
            result = listener.getImportResult();
            // 设置响应消息
            String message = String.format("成功导入 %d 条数据，失败 %d 条", result.getSuccessCount(), result.getFailureCount());
            // 返回带有正确泛型的响应
            return ResponseVO.<ImportResult>success(message, result);
        } catch (Exception e) {
            log.error("导入设备数据出错: {}", e.getMessage(), e);
            // 在异常情况下，设置默认结果
            String errorMessage = String.format("导入失败: %s。成功 %d 条，失败 %d 条", e.getMessage(), result.getSuccessCount(), result.getFailureCount());
            // 使用新方法确保类型正确
            return ResponseVO.<ImportResult>fail(errorMessage, result);
        }
    }

}


