package com.ygtx.gxt.controller.mobile;

import com.ygtx.common.annotation.Log;
import com.ygtx.common.core.controller.BaseController;
import com.ygtx.common.core.domain.AjaxResult;
import com.ygtx.common.core.page.TableDataInfo;
import com.ygtx.common.enums.BusinessType;
import com.ygtx.common.utils.StringUtils;
import com.ygtx.common.utils.sql.SqlUtil;
import com.ygtx.gxt.domain.*;
import com.ygtx.gxt.service.IGxtOrderMineService;
import com.ygtx.gxt.service.IGxtOrderScoreService;
import com.ygtx.gxt.service.IGxtRepairOrderService;
import com.ygtx.gxt.service.IGxtWorkOrderService;
import com.ygtx.gxt.service.impl.GxtOrderScoreServiceImpl;
import com.ygtx.system.service.ISysConfigService;
import io.lettuce.core.dynamic.annotation.Param;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.ygtx.common.utils.DateUtils;

/**
 * 工单Controller
 *
 * @date 2025-11-12
 */
@RestController
@RequestMapping("/mobile/order")
@Api(tags = "移动端工单管理")
public class GxtMobileOrderController extends BaseController
{
    @Autowired
    private IGxtRepairOrderService gxtRepairOrderService;

    @Autowired
    private IGxtWorkOrderService gxtWorkOrderService;

    @Autowired
    private IGxtOrderScoreService gxtOrderScoreService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IGxtOrderMineService gxtOrderMineService;

    /**
     * 查询超时工单列表
     */
    @ApiOperation("获取超时工单列表")
    @ApiImplicitParam(name = "keyword", value = "工单编码、风机编号", dataType = "String", dataTypeClass = String.class)
    @GetMapping("/overdue")
    public TableDataInfo overdueList(GxtWorkOrder workOrder, @Param("keyword") String keyword)
    {
        SqlUtil.filterKeyword(keyword);
        // 开启分页插件自动分页
        startPage();

        // 对 keyword 进行空格过滤处理
        if (keyword != null) {
            keyword = keyword.trim();
            if (keyword.isEmpty()) {
                keyword = null; // 视为空，不参与搜索
            }
        }
        // 查询超时工单列表

        // 创建维修工单查询条件
        GxtRepairOrder repairOrder = new GxtRepairOrder();

        // 设置超时条件参数
        Map<String, Object> params = new HashMap<>();
        params.put("overdueCondition", "overdue");
        repairOrder.setParams(params);
        workOrder.setParams(params);
        workOrder.setWorkOrderStatus("ignore");

        // 从selectMobileUnionOrderList获取数据
        List<OrderScoreInfo> list = gxtOrderScoreService.selectMobileUnionOrderList(repairOrder, workOrder, keyword);

        Date now = new Date();
        for (OrderScoreInfo order : list) {
            // 只处理维保工单（orderType == 2）
            if (order.getOrderType() == 2) {
                // accept_time为空，并且当前时间超过assign_time
                if (order.getAcceptTime() == null && order.getUpdateTime() != null &&
                    now.after(order.getUpdateTime())) {
                    // 计算超过的时间（按分钟计算）
                    long diffInMillis = now.getTime() - order.getUpdateTime().getTime();
                    long diffInMinutes = TimeUnit.MINUTES.convert(diffInMillis, TimeUnit.MILLISECONDS);

                    // 计算超时时间并格式化为X天X小时X分钟格式
                    long days = diffInMinutes / (24 * 60);
                    long hours = (diffInMinutes % (24 * 60)) / 60;
                    long minutes = diffInMinutes % 60;

                    StringBuilder remark = new StringBuilder("已超时");
                    if (days > 0) {
                        remark.append(days).append("天");
                    }
                    if (hours > 0) {
                        remark.append(hours).append("小时");
                    }
                    if (minutes > 0) {
                        remark.append(minutes).append("分钟");
                    }
                    order.setRemark(remark.toString());
                }
            }
            // 维修工单的超时逻辑
            else if (order.getOrderType() == 1) {
                // 对于维修工单，同样当前时间超过update_time
                if (order.getUpdateTime() != null && now.after(order.getUpdateTime())) {
                    // 计算超过的时间（按分钟计算）
                    long diffInMillis = now.getTime() - order.getUpdateTime().getTime();
                    long diffInMinutes = TimeUnit.MINUTES.convert(diffInMillis, TimeUnit.MILLISECONDS);

                    // 计算超时时间并格式化为X天X小时X分钟格式
                    long days = diffInMinutes / (24 * 60);
                    long hours = (diffInMinutes % (24 * 60)) / 60;
                    long minutes = diffInMinutes % 60;

                    StringBuilder remark = new StringBuilder("已超时");
                    if (days > 0) {
                        remark.append(days).append("天");
                    }
                    if (hours > 0) {
                        remark.append(hours).append("小时");
                    }
                    if (minutes > 0) {
                        remark.append(minutes).append("分钟");
                    }
                    order.setRemark(remark.toString());
                }
            }
        }

        return getDataTable(list);
    }

    /**
     * 查询即将超时工单列表
     */
    @ApiOperation("查询即将超时工单列表")
    @ApiImplicitParam(name = "keyword", value = "工单编码、风机编号", dataType = "String", dataTypeClass = String.class)
    @GetMapping("/almostOverdue")
    public TableDataInfo almostOverdueList(GxtWorkOrder workOrder, @Param("keyword") String keyword)
    {
        SqlUtil.filterKeyword(keyword);
        // 开启分页插件自动分页
        startPage();
        // 查询即将超时工单列表
        List<GxtWorkOrder> list = gxtWorkOrderService.selectAlmostOverdueWorkOrderList(workOrder, keyword);
        // 计算还差多少时间超时并格式化为X天X小时X分钟格式
        for (GxtWorkOrder order : list) {
            if (order.getPlanEndTime() != null && order.getRealEndTime() == null) {
                long diffInMillies = Math.abs(order.getPlanEndTime().getTime() - new Date().getTime());
                long diffInMinutes = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS);

                // 将分钟数转换为X天X小时X分钟格式
                long days = diffInMinutes / (24 * 60);
                long hours = (diffInMinutes % (24 * 60)) / 60;
                long minutes = diffInMinutes % 60;

                StringBuilder remark = new StringBuilder("剩余");
                if (days > 0) {
                    remark.append(days).append("天");
                }
                if (hours > 0) {
                    remark.append(hours).append("小时");
                }
                if (minutes > 0) {
                    remark.append(minutes).append("分钟");
                }
                order.setRemark(remark.toString());
            }
        }
        return getDataTable(list);
    }

    /**
     * 查询工单列表（合并维修工单和维保工单）
     */
    @ApiOperation("查询工单列表（合并维修工单和维保工单）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "workOrderStatus", value = "工单状态", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "keyword", value = "工单编码、风机编号", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/list")
    public TableDataInfo list(GxtRepairOrder repairOrder, GxtWorkOrder workOrder, @Param("keyword") String keyword)
    {
        SqlUtil.filterKeyword(keyword);
        // 开启分页插件自动分页
        startPage();
        // 对 keyword 进行空格过滤处理
        if (keyword != null) {
            keyword = keyword.trim();
            if (keyword.isEmpty()) {
                keyword = null; // 视为空，不参与搜索
            }
        }
        if ("pending".equals(repairOrder.getWorkOrderStatus())) {
            String dealStatusConfig = configService.selectConfigByKey("gxt.order.pending");
            repairOrder.setWorkOrderStatus(dealStatusConfig);
            workOrder.setWorkOrderStatus(dealStatusConfig);
        } else if ("all".equals(repairOrder.getWorkOrderStatus())) {
            repairOrder.setWorkOrderStatus(null);
            workOrder.setWorkOrderStatus(null);
        }
        // 查询合并的工单列表
        List<OrderScoreInfo> list = gxtOrderScoreService.selectMobileUnionOrderList(repairOrder, workOrder,keyword);
        return getDataTable(list);
    }

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

    /**
     * 获取维保工单详细信息
     */
    @ApiOperation("获取维保工单详细信息")
    @ApiImplicitParam(name = "id", value = "工单ID", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(gxtWorkOrderService.selectGxtWorkOrderById(id));
    }

    /**
     * 接单工单
     */
    @Log(title = "接单", businessType = BusinessType.UPDATE)
    @ApiOperation("接单工单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "工单ID", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orderType", value = "工单类型", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "workOrderStatus", value = "工单状态", dataType = "String", defaultValue = "to_finish", dataTypeClass = String.class),
            @ApiImplicitParam(name = "teamLeaderId", value = "负责人ID", dataType = "Long", paramType = "path", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "teamLeaderName", value = "负责人姓名", dataType = "String", dataTypeClass = String.class)
    })
    @PutMapping("/accept")
    public AjaxResult accept(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        if(gxtRepairOrder.getOrderType() == 1) {
            result = gxtRepairOrderService.acceptGxtRepairOrder(gxtRepairOrder);
        } else {
            GxtWorkOrder gxtWorkOrder = new GxtWorkOrder();
            gxtWorkOrder.setId(gxtRepairOrder.getId());
            gxtWorkOrder.setWorkOrderProjectNo(gxtRepairOrder.getWorkOrderProjectNo());
            gxtWorkOrder.setTeamLeaderId(gxtRepairOrder.getTeamLeaderId());
            gxtWorkOrder.setTeamLeaderName(gxtRepairOrder.getTeamLeaderName());
            gxtWorkOrder.setWorkOrderStatus(gxtRepairOrder.getWorkOrderStatus());
            result = gxtWorkOrderService.acceptOrder(gxtWorkOrder);
        }
        return toAjax(result);
    }

    /**
     * 挂起工单
     */
    @Log(title = "挂起", businessType = BusinessType.UPDATE)
    @ApiOperation("挂起工单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "工单ID", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orderType", value = "工单类型", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "workOrderStatus", value = "工单状态", dataType = "String", defaultValue = "to_approve", dataTypeClass = String.class),
            @ApiImplicitParam(name = "suspendReason", value = "挂起原因", dataType = "String", dataTypeClass = String.class)
    })
    @PutMapping("/suspend")
    public AjaxResult suspend(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        if(gxtRepairOrder.getOrderType() == 1) {
            if (StringUtils.isNotEmpty(gxtRepairOrder.getRejectionReason()) && "4".equals(gxtRepairOrder.getSuspendReason())) {
                gxtRepairOrder.setSuspendExplain(gxtRepairOrder.getRejectionReason()); //  app前端挂起说明暂存在rejectionReason里
                gxtRepairOrder.setRejectionReason(null);
            }
            result = gxtRepairOrderService.suspendGxtRepairOrder(gxtRepairOrder);
        } else {
            GxtWorkOrder gxtWorkOrder = new GxtWorkOrder();
            gxtWorkOrder.setId(gxtRepairOrder.getId());
            gxtWorkOrder.setSuspendReason(gxtRepairOrder.getSuspendReason());
            gxtWorkOrder.setWorkOrderStatus(gxtRepairOrder.getWorkOrderStatus());
            if (StringUtils.isNotEmpty(gxtRepairOrder.getRejectionReason()) && "4".equals(gxtRepairOrder.getSuspendReason())) {
                gxtWorkOrder.setSuspendExplain(gxtRepairOrder.getRejectionReason()); //  app前端挂起说明暂存在rejectionReason里
                gxtWorkOrder.setRejectionReason(null);
            }
            result = gxtWorkOrderService.suspendWorkOrder(gxtWorkOrder);
        }
        return toAjax(result);
    }

    /**
     * 审批工单
     */
    @Log(title = "审批", businessType = BusinessType.UPDATE)
    @ApiOperation("审批工单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "工单ID", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orderType", value = "工单类型", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "workOrderStatus", value = "工单状态", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "rejectionReason", value = "审批意见", dataType = "String", dataTypeClass = String.class)
    })
    @PutMapping("/approve")
    public AjaxResult approve(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        if(gxtRepairOrder.getOrderType() == 1) {
            if ("to_finish".equals(gxtRepairOrder.getWorkOrderStatus())) {
                gxtRepairOrder.setApprovalStatus("rejected");
            } else {
                gxtRepairOrder.setApprovalStatus("approved");
            }
            result = gxtRepairOrderService.approveSuspendGxtRepairOrder(gxtRepairOrder);
        } else {
            GxtWorkOrder gxtWorkOrder = new GxtWorkOrder();
            gxtWorkOrder.setId(gxtRepairOrder.getId());
            gxtWorkOrder.setRejectionReason(gxtRepairOrder.getRejectionReason());
            gxtWorkOrder.setWorkOrderStatus(gxtRepairOrder.getWorkOrderStatus());
            result = gxtWorkOrderService.approveWorkOrder(gxtWorkOrder);
        }
        return toAjax(result);
    }

    /**
     * 恢复工单
     */
    @Log(title = "恢复", businessType = BusinessType.UPDATE)
    @ApiOperation("恢复工单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "工单ID", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orderType", value = "工单类型", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "workOrderStatus", value = "工单状态", dataType = "String", defaultValue = "to_approve", dataTypeClass = String.class),
    })
    @PutMapping("/resume")
    public AjaxResult resume(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        if(gxtRepairOrder.getOrderType() == 1) {
            result = gxtRepairOrderService.resumeGxtRepairOrder(gxtRepairOrder);
        } else {
            GxtWorkOrder gxtWorkOrder = new GxtWorkOrder();
            gxtWorkOrder.setId(gxtRepairOrder.getId());
            gxtWorkOrder.setWorkOrderStatus(gxtRepairOrder.getWorkOrderStatus());
            result = gxtWorkOrderService.resumeWorkOrder(gxtWorkOrder);
        }
        return toAjax(result);
    }

    /**
     * 查询待处理工单列表（合并维修工单和维保工单）
     */
    @ApiOperation("查询待处理工单列表（合并维修工单和维保工单）")
    @ApiImplicitParam(name = "keyword", value = "工单编码、风机编号", dataType = "String", paramType = "query", dataTypeClass = String.class)
    @GetMapping("/pendingList")
    public TableDataInfo pendingList(GxtRepairOrder repairOrder, GxtWorkOrder workOrder, @Param("keyword") String keyword)
    {
        SqlUtil.filterKeyword(keyword);
        // 开启分页插件自动分页
        startPage();
        // 对 keyword 进行空格过滤处理
        if (keyword != null) {
            keyword = keyword.trim();
            if (keyword.isEmpty()) {
                keyword = null; // 视为空，不参与搜索
            }
        }
        repairOrder.getParams().put("keyword", keyword);
        workOrder.getParams().put("keyword", keyword);
        // 查询合并的工单列表
         List<OrderScoreInfo> list = gxtOrderMineService.selectUnionOrderListMyTodo(repairOrder, workOrder, null);
        return getDataTable(list);
    }

    /**
     * 查询我的待评分工单列表（合并维修工单和维保工单）
     */
    @ApiOperation("查询我的待评分工单列表（合并维修工单和维保工单）")
    @ApiImplicitParam(name = "keyword", value = "工单编码、风机编号", dataType = "String", paramType = "query", dataTypeClass = String.class)
    @GetMapping("/listMyRate")
    public TableDataInfo listMyRate(GxtRepairOrder repairOrder, GxtWorkOrder workOrder, @Param("keyword") String keyword)
    {
        SqlUtil.filterKeyword(keyword);
        // 开启分页插件自动分页
        startPage();
        // 对 keyword 进行空格过滤处理
        if (keyword != null) {
            keyword = keyword.trim();
            if (keyword.isEmpty()) {
                keyword = null; // 视为空，不参与搜索
            }
        }
        repairOrder.getParams().put("keyword", keyword);
        workOrder.getParams().put("keyword", keyword);
        // 查询合并的工单列表
        List<OrderScoreInfo> list = gxtOrderMineService.selectUnionOrderListMyRate(repairOrder, workOrder);
        return getDataTable(list);
    }

    @PutMapping("/returnRepairOrder")
    public AjaxResult returnGxtRepairOrder(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        if (gxtRepairOrder.getWorkOrderStatus().equals("return") || gxtRepairOrder.getWorkOrderStatus().equals("assigned")) {
            gxtRepairOrder.setWorkOrderStatus("accept_return");
        } else {
            gxtRepairOrder.setWorkOrderStatus("return");
        }
        result = gxtRepairOrderService.returnGxtRepairOrder(gxtRepairOrder);

        return toAjax(result);
    }

    @PutMapping("/resetAndStart")
    public AjaxResult resetAndStart(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;


        result = gxtRepairOrderService.finalizeGxtRepairOrder(gxtRepairOrder);

        return toAjax(result);
    }

    /**
     * 结单工单
     */
    @Log(title = "结单", businessType = BusinessType.UPDATE)
    @ApiOperation("维保结单工单")
    @PutMapping("/finish")
    public AjaxResult finishOrder(@RequestBody GxtWorkOrder gxtWorkOrder)
    {
        int result = 0;
        result = gxtWorkOrderService.completeWorkOrder(gxtWorkOrder);
        return toAjax(result);
    }
    /**
     * 结单工单
     */
    @Log(title = "结单", businessType = BusinessType.UPDATE)
    @ApiOperation("维修结单工单")
    @PutMapping("/repairFinish")
    public AjaxResult repairFinishOrder(@RequestBody GxtRepairOrder gxtRepairOrder)
    {
        int result = 0;
        result = gxtRepairOrderService.finalizeGxtRepairOrder(gxtRepairOrder);
        return toAjax(result);
    }

    /**
     * 维保停机
     * @param gxtWorkOrder
     * @return
     */
    @Log(title = "停机", businessType = BusinessType.UPDATE)
    @ApiOperation("停机")
    @PutMapping("/shutdown")
    public AjaxResult shutdown(@RequestBody GxtWorkOrder gxtWorkOrder)
    {
        return toAjax(gxtWorkOrderService.shutdownOrder(gxtWorkOrder));
    }
}
