package com.ruoyi.web.controller.customer;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;

import com.ruoyi.system.domain.UserSessions;
import com.ruoyi.system.domain.ManualServiceSessions;
import com.ruoyi.customer.service.ICustomerServiceService;
import com.ruoyi.system.domain.ChatHistory;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.web.controller.customer.dto.TransferToManualRequest;
import com.ruoyi.web.websocket.CustomerServiceWebSocket;

/**
 * 客服系统Controller
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Controller
@RequestMapping("/customer/service")
public class CustomerServiceController extends BaseController
{
    private String prefix = "customer/service";

    @Autowired
    private ICustomerServiceService customerServiceService;

    @RequiresPermissions("customer:service:view")
    @GetMapping()
    public String service()
    {
        return prefix + "/index";
    }

    /**
     * 查询会话列表
     */
    @RequiresPermissions("customer:service:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(UserSessions userSessions)
    {
        startPage();
        List<UserSessions> list = customerServiceService.selectUserSessionsList(userSessions);
        return getDataTable(list);
    }

    /**
     * 获取所有活跃会话
     */
    @GetMapping("/sessions")
    @ResponseBody
    public AjaxResult getSessions()
    {
        try {
            List<UserSessions> sessions = customerServiceService.getActiveSessions();
            return AjaxResult.success(sessions);
        } catch (Exception e) {
            logger.error("获取会话列表失败", e);
            return AjaxResult.error("获取会话列表失败");
        }
    }

    /**
     * 获取指定会话信息
     */
    @GetMapping("/sessions/{sessionId}")
    @ResponseBody
    public AjaxResult getSession(@PathVariable String sessionId)
    {
        try {
            UserSessions session = customerServiceService.selectUserSessionsById(sessionId);
            return AjaxResult.success(session);
        } catch (Exception e) {
            logger.error("获取会话信息失败", e);
            return AjaxResult.error("获取会话信息失败");
        }
    }

    /**
     * 获取会话聊天记录
     */
    @GetMapping("/messages/{sessionId}")
    @ResponseBody
    public AjaxResult getChatHistory(@PathVariable String sessionId)
    {
        try {
            List<ChatHistory> messages = customerServiceService.getChatHistoryBySessionId(sessionId);
            return AjaxResult.success(messages);
        } catch (Exception e) {
            logger.error("获取聊天记录失败", e);
            return AjaxResult.error("获取聊天记录失败");
        }
    }

    /**
     * 发送消息
     */
    @PostMapping("/send")
    @ResponseBody
    public AjaxResult sendMessage(@RequestParam String sessionId, @RequestParam String content, @RequestParam String senderType) {
        try {
            // 根据sessionId查找对应的用户ID
            UserSessions userSession = customerServiceService.selectUserSessionsById(sessionId);
            if (userSession == null) {
                return AjaxResult.error("会话不存在");
            }
            
            // 创建聊天记录
            ChatHistory chatHistory = new ChatHistory();
            chatHistory.setSessionId(sessionId);
            chatHistory.setContent(content);
            chatHistory.setUserId(userSession.getUserId().toString()); // 设置为客户的userId
            chatHistory.setSenderId(getUserId()); // 发送者ID为当前登录的客服ID
            chatHistory.setSenderType("SERVICE"); // 发送者类型为客服
            chatHistory.setMessageType("service"); // 消息类型为客服消息
            chatHistory.setCreateTime(new java.util.Date());
            
            // 保存聊天记录
            customerServiceService.insertChatHistory(chatHistory);
            
            // 通过WebSocket发送消息给客户端
            // 创建JSON格式的WebSocket消息
            com.alibaba.fastjson.JSONObject wsMessage = new com.alibaba.fastjson.JSONObject();
            wsMessage.put("type", "message");
            wsMessage.put("content", content);
            
            // 发送JSON格式的WebSocket消息给客户端
            CustomerServiceWebSocket.sendInfo(wsMessage.toJSONString(), userSession.getUserId().toString());
            
            logger.info("[发送消息] WebSocket消息已发送 - userId: {}, sessionId: {}, content: {}, messageFormat: JSON", 
                       userSession.getUserId(), sessionId, content);
            
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("发送消息失败", e);
            return AjaxResult.error("发送消息失败: " + e.getMessage());
        }
    }

    /**
     * 转人工服务
     */
    @PostMapping("/transfer")
    @ResponseBody
    public AjaxResult transferToManual(@RequestBody TransferToManualRequest request, HttpServletRequest httpRequest)
    {
        logger.info("[转人工服务] 收到转人工请求 - 原始请求: {}", request);
        logger.info("[转人工服务] 请求头信息 - Authorization: {}, Content-Type: {}", 
                   httpRequest.getHeader("Authorization"), httpRequest.getHeader("Content-Type"));
        
        // 解析参数
        Long userId = request.getUserIdAsLong();
        String reason = request.getReasonAsString();
        
        logger.info("[转人工服务] 解析后参数 - userId: {}, reason: {}", userId, reason);
        logger.info("[转人工服务] 请求参数验证 - userId是否为空: {}, reason是否为空: {}", 
                   userId == null, reason == null || reason.trim().isEmpty());
        
        // 参数验证
        if (userId == null) {
            logger.error("[转人工服务] 参数验证失败 - userId为空或格式错误，原始值: {}", request.getUserId());
            return AjaxResult.error("用户ID不能为空或格式错误");
        }
        
        if (reason == null || reason.trim().isEmpty()) {
            logger.error("[转人工服务] 参数验证失败 - reason为空");
            return AjaxResult.error("转人工原因不能为空");
        }
        
        try {
            // 生成或查找SessionId
            String sessionId = generateOrFindSessionId(userId);
            logger.info("[转人工服务] SessionId生成结果 - userId: {}, sessionId: {}", userId, sessionId);
            
            // 防重复提交：检查是否已有待处理的转人工记录
            List<ManualServiceSessions> existingRequests = customerServiceService.getPendingManualRequestsByUserId(userId);
            if (existingRequests != null && !existingRequests.isEmpty()) {
                logger.warn("[转人工服务] 该用户已有待处理的转人工记录 - userId: {}, 数量: {}", userId, existingRequests.size());
                return AjaxResult.error("您已提交转人工请求，请等待客服处理");
            }
            
            ManualServiceSessions manualSession = new ManualServiceSessions();
            manualSession.setUserId(userId);
            // 设置会话ID为字符串类型的UUID
            manualSession.setSessionId(sessionId);
            manualSession.setReason(reason.trim());
            manualSession.setStatus("0"); // 0-待处理
            manualSession.setRequestTime(new java.util.Date());
            manualSession.setCreateBy(userId.toString());
            
            logger.info("[转人工服务] 准备插入数据库 - 转人工会话对象: userId={}, sessionId={}, reason={}, status={}", 
                       manualSession.getUserId(), manualSession.getSessionId(), 
                       manualSession.getReason(), manualSession.getStatus());
            
            int result = customerServiceService.createManualServiceRequest(manualSession);
            logger.info("[转人工服务] 数据库插入结果: {}", result);
            
            if (result > 0) {
                logger.info("[转人工服务] 转人工请求提交成功 - userId: {}, sessionId: {}", userId, sessionId);
                // 返回sessionId给前端
                Map<String, Object> responseData = new HashMap<>();
                responseData.put("sessionId", sessionId);
                responseData.put("message", "转人工请求已提交，请等待客服接听");
                return AjaxResult.success(responseData);
            } else {
                logger.error("[转人工服务] 转人工请求提交失败 - 数据库插入返回0");
                return AjaxResult.error("转人工请求提交失败");
            }
        } catch (Exception e) {
            logger.error("[转人工服务] 转人工服务异常 - userId: {}, reason: {}", userId, reason, e);
            return AjaxResult.error("转人工服务失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成或查找SessionId
     * 方案1：在转人工接口中按需生成SessionId
     */
    private String generateOrFindSessionId(Long userId) {
        try {
            // 1. 先查找用户是否有活跃的会话
            String existingSessionId = customerServiceService.findActiveSessionByUserId(userId);
            if (existingSessionId != null && !existingSessionId.trim().isEmpty()) {
                logger.info("[SessionId生成] 找到用户活跃会话 - userId: {}, sessionId: {}", userId, existingSessionId);
                return existingSessionId;
            }
            
            // 2. 如果没有活跃会话，生成新的SessionId
            String newSessionId = java.util.UUID.randomUUID().toString().replace("-", "");
            logger.info("[SessionId生成] 生成新的SessionId - userId: {}, newSessionId: {}", userId, newSessionId);
            
            // 3. 可选：将新的SessionId保存到用户会话表中
            // customerServiceService.createUserSession(userId, newSessionId);
            
            return newSessionId;
        } catch (Exception e) {
            logger.error("[SessionId生成] 生成SessionId异常 - userId: {}", userId, e);
            // 异常情况下返回基于userId的默认SessionId
            return "session_" + userId + "_" + System.currentTimeMillis();
        }
    }

    /**
     * 获取转人工请求列表
     */
    @GetMapping("/manual-requests")
    @ResponseBody
    public AjaxResult getManualRequests()
    {
        try {
            List<ManualServiceSessions> requests = customerServiceService.getPendingManualRequests();
            return AjaxResult.success(requests);
        } catch (Exception e) {
            logger.error("获取转人工请求失败", e);
            return AjaxResult.error("获取转人工请求失败");
        }
    }

    /**
     * 获取单个转人工请求详情
     */
    @GetMapping("/manual-requests/{requestId}")
    @ResponseBody
    public AjaxResult getManualRequestById(@PathVariable Long requestId)
    {
        try {
            logger.info("[获取转人工请求详情] 开始处理请求 - requestId: {}", requestId);
            
            ManualServiceSessions request = customerServiceService.getManualRequestById(requestId);
            if (request == null) {
                logger.error("[获取转人工请求详情] 未找到转人工记录 - requestId: {}", requestId);
                return AjaxResult.error("未找到转人工记录");
            }
            
            logger.info("[获取转人工请求详情] 成功获取记录 - userId: {}, sessionId: {}, status: {}", 
                       request.getUserId(), request.getSessionId(), request.getStatus());
            return AjaxResult.success(request);
        } catch (Exception e) {
            logger.error("[获取转人工请求详情] 获取转人工请求详情失败 - requestId: {}", requestId, e);
            return AjaxResult.error("获取转人工请求详情失败: " + e.getMessage());
        }
    }

    /**
     * 接受转人工请求
     */
    @PostMapping("/manual-requests/{requestId}/accept")
    @ResponseBody
    public AjaxResult acceptManualRequest(@PathVariable Long requestId)
    {
        try {
            logger.info("[接受转人工] 开始处理请求 - requestId: {}, serviceId: {}", requestId, getUserId());
            
            // 先获取原始记录
            ManualServiceSessions originalRequest = customerServiceService.getManualRequestById(requestId);
            if (originalRequest == null) {
                logger.error("[接受转人工] 未找到转人工记录 - requestId: {}", requestId);
                return AjaxResult.error("未找到转人工记录");
            }
            
            logger.info("[接受转人工] 原始记录 - userId: {}, sessionId: {}, status: {}", 
                       originalRequest.getUserId(), originalRequest.getSessionId(), originalRequest.getStatus());
            
            // 检查状态是否为待处理
            if (!"0".equals(originalRequest.getStatus())) {
                logger.warn("[接受转人工] 记录状态不是待处理 - status: {}", originalRequest.getStatus());
                return AjaxResult.error("该请求已被处理");
            }
            
            // 更新记录状态
            ManualServiceSessions manualSession = new ManualServiceSessions();
            manualSession.setManualSessionId(requestId); // 设置主键ID
            manualSession.setStatus("1"); // 1-已接受
            manualSession.setServiceId(getUserId());
            manualSession.setAcceptTime(new java.util.Date());
            manualSession.setUpdateBy(requestId+"");
            
            int result = customerServiceService.updateManualServiceRequest(manualSession);
            logger.info("[接受转人工] 数据库更新结果: {}", result);
            
            if (result > 0) {
                // 创建或更新UserSessions记录
                try {
                    String sessionId = originalRequest.getSessionId();
                    boolean sessionExists = customerServiceService.isSessionIdExists(sessionId);
                    
                    UserSessions userSession = new UserSessions();
                    userSession.setSessionId(sessionId);
                    userSession.setUserId(originalRequest.getUserId());
                    userSession.setSessionStart(new java.util.Date());
                    userSession.setStatus("active");
                    userSession.setLastActivity(new java.util.Date());
                    userSession.setSessionToken(sessionId);
                    
                    int sessionResult;
                    if (sessionExists) {
                        // 如果会话已存在，则更新记录
                        sessionResult = customerServiceService.updateUserSessions(userSession);
                        logger.info("[接受转人工] 更新UserSessions记录结果: {}", sessionResult);
                    } else {
                        // 如果会话不存在，则插入新记录
                        sessionResult = customerServiceService.insertUserSessions(userSession);
                        logger.info("[接受转人工] 创建UserSessions记录结果: {}", sessionResult);
                    }
                } catch (Exception e) {
                    logger.error("[接受转人工] 处理UserSessions记录失败", e);
                }
                
                // 通知用户转人工请求被接受
                if (originalRequest.getUserId() != null) {
                    logger.info("[接受转人工] 发送用户通知 - userId: {}", originalRequest.getUserId());
                    customerServiceService.notifyUserManualRequestAccepted(
                        originalRequest.getUserId(), requestId, getUserId());
                } else {
                    logger.warn("[接受转人工] 原始记录中userId为空，无法发送用户通知");
                }
                
                logger.info("[接受转人工] 处理完成 - 成功接受转人工请求");
                return AjaxResult.success("已接受转人工请求");
            } else {
                logger.error("[接受转人工] 数据库更新失败");
                return AjaxResult.error("操作失败");
            }
        } catch (Exception e) {
            logger.error("[接受转人工] 处理异常", e);
            return AjaxResult.error("操作失败: " + e.getMessage());
        }
    }

    /**
     * 拒绝转人工请求
     */
    @PostMapping("/manual-requests/{requestId}/reject")
    @ResponseBody
    public AjaxResult rejectManualRequest(@PathVariable Long requestId)
    {
        try {
            ManualServiceSessions manualSession = new ManualServiceSessions();
            manualSession.setManualSessionId(requestId); // 设置主键ID
            manualSession.setStatus("2"); // 2-已拒绝
            manualSession.setServiceId(getUserId());
            manualSession.setUpdateBy(requestId+"");
            
            int result = customerServiceService.updateManualServiceRequest(manualSession);
            if (result > 0) {
                return AjaxResult.success("已拒绝转人工请求");
            } else {
                return AjaxResult.error("操作失败");
            }
        } catch (Exception e) {
            logger.error("拒绝转人工请求失败", e);
            return AjaxResult.error("操作失败: " + e.getMessage());
        }
    }

    /**
     * 更新客服状态
     */
    @PostMapping("/status")
    @ResponseBody
    public AjaxResult updateServiceStatus(@RequestParam String status)
    {
        try {
            logger.info("[更新客服状态] 收到请求参数 - serviceId: {}, status: {}", getUserId(), status);
            
            int result = customerServiceService.updateServiceStatus(getUserId(), status);
            if (result > 0) {
                logger.info("[更新客服状态] 状态更新成功");
                return AjaxResult.success("状态更新成功");
            } else {
                logger.error("[更新客服状态] 状态更新失败 - 数据库返回0");
                return AjaxResult.error("状态更新失败");
            }
        } catch (Exception e) {
            logger.error("[更新客服状态] 更新客服状态异常", e);
            return AjaxResult.error("状态更新失败: " + e.getMessage());
        }
    }

    /**
     * 导出会话列表
     */
    @RequiresPermissions("customer:service:export")
    @Log(title = "客服会话", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(@RequestBody UserSessions userSessions)
    {
        try {
            logger.info("[导出会话] 收到导出请求 - 查询条件: {}", userSessions);
            
            List<UserSessions> list = customerServiceService.selectUserSessionsList(userSessions);
            logger.info("[导出会话] 查询到数据条数: {}", list != null ? list.size() : 0);
            
            ExcelUtil<UserSessions> util = new ExcelUtil<UserSessions>(UserSessions.class);
            AjaxResult result = util.exportExcel(list, "会话数据");
            
            logger.info("[导出会话] 导出完成");
            return result;
        } catch (Exception e) {
            logger.error("[导出会话] 导出会话列表异常", e);
            return AjaxResult.error("导出失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/current-user")
    @ResponseBody
    public AjaxResult getCurrentUser()
    {
        try {
            Long userId = getUserId();
            String loginName = getLoginName();
            
            AjaxResult result = AjaxResult.success();
            result.put("userId", userId);
            result.put("loginName", loginName);
            
            return result;
        } catch (Exception e) {
            logger.error("获取当前用户信息失败", e);
            return AjaxResult.error("获取当前用户信息失败");
        }
    }

    /**
     * 获取客服统计信息
     */
    @GetMapping("/statistics")
    @ResponseBody
    public AjaxResult getStatistics()
    {
        try {
            // 获取今日统计数据
            int todaySessions = customerServiceService.getTodaySessionCount();
            int todayMessages = customerServiceService.getTodayMessageCount();
            int pendingRequests = customerServiceService.getPendingRequestCount();
            int onlineServices = customerServiceService.getOnlineServiceCount();
            
            AjaxResult result = AjaxResult.success();
            result.put("todaySessions", todaySessions);
            result.put("todayMessages", todayMessages);
            result.put("pendingRequests", pendingRequests);
            result.put("onlineServices", onlineServices);
            
            return result;
        } catch (Exception e) {
            logger.error("获取统计信息失败", e);
            return AjaxResult.error("获取统计信息失败");
        }
    }
}