package com.ygtx.gxt.controller;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.github.pagehelper.util.StringUtil;
import com.ygtx.common.utils.DictUtils;
import com.ygtx.common.utils.SecurityUtils;
import com.ygtx.gxt.domain.GxtOrderData;
import com.ygtx.gxt.service.IGxtWorkOrderService;
import com.ygtx.system.service.ISysConfigService;
import com.ygtx.system.strategy.AutoCodeUtil;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ygtx.common.annotation.Log;
import com.ygtx.common.core.controller.BaseController;
import com.ygtx.common.core.domain.AjaxResult;
import com.ygtx.common.enums.BusinessType;
import com.ygtx.gxt.domain.GxtRepairOrder;
import com.ygtx.gxt.service.IGxtRepairOrderService;
import com.ygtx.common.utils.poi.ExcelUtil;
import com.ygtx.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;

/**
 * 维修工单Controller
 *
 * @author ouyj
 * @date 2025-10-30
 */
@RestController
@RequestMapping("/gxt/repairOrder")
@Api(tags = "维修工单管理")
public class GxtRepairOrderController extends BaseController
{
    @Autowired
    private IGxtRepairOrderService gxtRepairOrderService;
    @Autowired
    private ResourceLoader resourceLoader;
    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private IGxtWorkOrderService gxtWorkOrderService;
    @Autowired
    private ISysConfigService configService;

    /**
     * 查询维修工单列表
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:list')")
    @GetMapping("/list")
    @ApiOperation("查询维修工单列表")
    public TableDataInfo list(GxtRepairOrder gxtRepairOrder)
    {
        startPage();
        List<GxtRepairOrder> list = gxtRepairOrderService.selectGxtRepairOrderList(gxtRepairOrder);
        return getDataTable(list);
    }

    /**
     * 导出维修工单列表
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:export')")
    @Log(title = "维修工单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation("导出维修工单列表")
    public void export(HttpServletResponse response, GxtRepairOrder gxtRepairOrder, 
                       @RequestParam(value = "exportFields", required = false) String exportFieldsStr) {
        List<GxtRepairOrder> list = gxtRepairOrderService.selectGxtRepairOrderList(gxtRepairOrder);
        // 将工单状态值转换为标签
        for (GxtRepairOrder order : list) {
            String statusLabel = DictUtils.getDictLabel("gxt_work_order_status", order.getWorkOrderStatus());
            order.setWorkOrderStatusName(statusLabel);
        }
        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        if (exportFieldsStr != null && !exportFieldsStr.isEmpty()) {
            // 将字符串分割成数组
            String[] exportFields = exportFieldsStr.split(",");
            util.showColumn(exportFields);
        }
        util.exportExcel(response, list, "维修工单数据");
    }

    /**
     * 获取维修工单导出字段列表
     */
    @GetMapping("/exportFields")
    @ApiOperation("获取维修工单导出字段列表")
    public AjaxResult getExportFields() {
        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        return success(util.getExportFields());
    }

    /**
     * 获取维修工单详细信息
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation("获取维修工单详细信息")
    @ApiImplicitParam(name = "id", value = "工单ID", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(gxtRepairOrderService.selectGxtRepairOrderById(id));
    }

    /**
     * 新增维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:add')")
    @Log(title = "维修工单", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation("新增维修工单")
    public AjaxResult add(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        if (!gxtRepairOrderService.checkWorkOrderProjectNoUnique(gxtRepairOrder)) {
            return error("新增工单编码'" + gxtRepairOrder.getWorkOrderProjectNo() + "'失败，工单编码已存在");
        }
        return toAjax(gxtRepairOrderService.insertGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 修改维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:edit')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("下发维修工单")
    public AjaxResult edit(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        if (!gxtRepairOrderService.checkWorkOrderProjectNoUnique(gxtRepairOrder)) {
            return error("修改工单编码'" + gxtRepairOrder.getWorkOrderProjectNo() + "'失败，工单编码已存在");
        }
        return toAjax(gxtRepairOrderService.updateGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 删除维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:remove')")
    @Log(title = "维修工单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    @ApiOperation("删除维修工单")
    @ApiImplicitParam(name = "ids", value = "工单ID数组", required = true, dataType = "Long[]", paramType = "path", dataTypeClass = Long[].class)
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(gxtRepairOrderService.deleteGxtRepairOrderByIds(ids));
    }

    /**
     * 派单维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:assign')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/assign")
    @ApiOperation("派单维修工单")
    public AjaxResult assign(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.assignGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 接单维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:accept')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/accept")
    @ApiOperation("接单维修工单")
    public AjaxResult accept(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.acceptGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 开始维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:start')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/start")
    @ApiOperation("开始维修工单")
    public AjaxResult start(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.startGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 暂停维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:pause')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/pause")
    @ApiOperation("暂停维修工单")
    public AjaxResult pause(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.pauseGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 挂起维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:suspend')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/suspend")
    @ApiOperation("挂起维修工单")
    public AjaxResult suspend(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.suspendGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 审批挂起维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:approve')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/approve")
    @ApiOperation("审批挂起维修工单")
    public AjaxResult approve(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.approveSuspendGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 恢复维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:resume') or @ss.hasPermi('gxt:repairOrder:autoResume')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/resume")
    @ApiOperation("恢复维修工单")
    public AjaxResult resume(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.resumeGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 维修处理完成（进入待结单状态）
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:processDone')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/processDone")
    @ApiOperation("维修处理完成（进入待结单状态）")
    public AjaxResult processDone(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.processDoneGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 正式结单（完结工单）
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:finalize')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/finalize")
    @ApiOperation("正式结单（完结工单）")
    public AjaxResult finalize(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.finalizeGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 评分维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:rating')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/rating")
    @ApiOperation("评分维修工单")
    public AjaxResult rating(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.ratingGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 复运维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:restart')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/restart")
    @ApiOperation("复运维修工单")
    public AjaxResult restart(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.restartGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 导入MIS工单数据
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:importMis')")
    @Log(title = "维修工单", businessType = BusinessType.IMPORT)
    @PostMapping("/importDataMis")
    @ApiOperation("导入MIS工单数据")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "file", value = "MIS工单文件", required = true, dataType = "MultipartFile", dataTypeClass = MultipartFile.class),
        @ApiImplicitParam(name = "updateSupport", value = "是否更新支持", required = true, dataType = "boolean", dataTypeClass = Boolean.class)
    })
    public AjaxResult importDataMis(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        List<GxtRepairOrder> repairOrderList = util.importExcel(file.getInputStream());
        String operName = getUsername();
        String message = gxtRepairOrderService.importGxtRepairOrderMis(repairOrderList, updateSupport, operName);
        return success(message);
    }

    /**
     * 下载MIS工单导入模板
     */
    @PostMapping("/importTemplateMis")
    @ApiOperation("下载MIS工单导入模板")
    public void importTemplateMis(HttpServletResponse response)
    {
        /*ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        util.importTemplateExcel(response, "维修工单数据");*/
        try {
            String filename = URLEncoder.encode("repairOrder.xlsx", StandardCharsets.UTF_8.toString());
            Resource resource = resourceLoader.getResource("classpath:repairOrderMis.xlsx");
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            try (ServletOutputStream out = response.getOutputStream();
                 InputStream stream = resource.getInputStream()) {
                byte buff[] = new byte[1024];
                int length;
                // 从文件输入流读取数据，并写入响应输出流中，实现文件下载
                while ((length = stream.read(buff)) > 0) {
                    out.write(buff, 0, length);
                }
                out.flush(); // 刷新输出流，确保所有数据都被发送到客户端
            }
        } catch (IOException e) {
            e.printStackTrace(); // 输出异常信息，便于排查问题
        }
    }

    /**
     * 导入维修工单数据
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:import')")
    @Log(title = "维修工单", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    @ApiOperation("导入维修工单数据")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "file", value = "维修工单文件", required = true, dataType = "MultipartFile", dataTypeClass = MultipartFile.class),
        @ApiImplicitParam(name = "updateSupport", value = "是否更新支持", required = true, dataType = "boolean", dataTypeClass = Boolean.class)
    })
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        List<GxtRepairOrder> repairOrderList = util.importExcel(file.getInputStream());
        String operName = getUsername();
        String message = gxtRepairOrderService.importGxtRepairOrder(repairOrderList, updateSupport, operName);
        return success(message);
    }

    /**
     * 下载维修工单导入模板
     */
    @PostMapping("/importTemplate")
    @ApiOperation("下载维修工单导入模板")
    public void importTemplate(HttpServletResponse response)
    {
        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
        util.importTemplateExcel(response, "维修工单数据");
    }

    /**
     * 根据MIS工单编码查询MIS工单信息
     */
    @GetMapping(value = "/getInfoByMisOrderNo")
    @ApiOperation("根据MIS工单编码查询MIS工单信息")
    public AjaxResult getInfoByMisOrderNo(GxtRepairOrder repairOrder)
    {
        return success(gxtRepairOrderService.selectGxtRepairOrderByMisOrderNo(repairOrder));
    }

    @GetMapping(value = "/selectHomePageData")
    @ApiOperation("获取首页数据")
    public AjaxResult selectHomePageData()
    {
        GxtOrderData result = gxtRepairOrderService.selectHomePageData();
        result.setNickName(SecurityUtils.getLoginUser().getUser().getNickName());
        result.setRepairPending(gxtRepairOrderService.getUnfinishedOrder());
        result.setWorkPending(gxtWorkOrderService.getUnfinishedOrder());
        result.setHasCenter(gxtWorkOrderService.hasCenter());
        String num = configService.selectConfigByKey("gxt.order.timeout");
        GxtRepairOrder gxtRepairOrder = new GxtRepairOrder();
        gxtRepairOrder.setWorkOrderStatus("assigned");
        if (StringUtil.isNotEmpty(num)) {
            gxtRepairOrder.setOutTimeParam(Integer.valueOf(num));
        }
        List<GxtRepairOrder> orders = gxtRepairOrderService.selectGxtRepairOrderList(gxtRepairOrder);
        result.setTimeOutNum(orders.size());
        return success(result);
    }

    /**
     * 撤回维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:revoke')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/revoke")
    @ApiOperation("撤回维修工单")
    public AjaxResult revoke(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.revokeGxtRepairOrder(gxtRepairOrder));
    }
    
    /**
     * 作废维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:invalidate')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/invalidate")
    @ApiOperation("作废维修工单")
    public AjaxResult invalidate(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.invalidateGxtRepairOrder(gxtRepairOrder));
    }

    /**
     * 退回维修工单
     */
    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:return') or @ss.hasPermi('gxt:repairOrder:acceptReturn')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/return")
    @ApiOperation("退回维修工单")
    public AjaxResult returnWork(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        return toAjax(gxtRepairOrderService.returnGxtRepairOrder(gxtRepairOrder));
    }
}