package com.snack.server.module.chat.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.server.common.Result;
import com.snack.server.module.chat.dto.req.ChatAckReq;
import com.snack.server.module.chat.dto.req.ChatSendMessageReq;
import com.snack.server.module.chat.entity.ChatSession;
import com.snack.server.module.chat.service.ChatMessageService;
import com.snack.server.module.chat.service.ChatOnlineService;
import com.snack.server.module.chat.service.ChatSessionService;
import com.snack.server.module.chat.vo.ChatMessageVO;
import com.snack.server.module.chat.vo.ChatSessionDetailVO;
import com.snack.server.module.chat.vo.ChatSessionVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 客服聊天 - 用户端 API
 */
@Tag(name = "客服聊天（用户端）")
@RestController
@RequestMapping("/api/chat")
@RequiredArgsConstructor
public class ChatUserController {

    private final ChatSessionService chatSessionService;
    private final ChatMessageService chatMessageService;
    private final ChatOnlineService chatOnlineService;

    @Operation(summary = "创建/恢复会话 - 获取或创建当前可用会话")
    @SaCheckLogin
    @PostMapping("/session")
    public Result<ChatSessionDetailVO> createOrRestoreSession() {
        Long userId = StpUtil.getLoginIdAsLong();
        ChatSession session = chatSessionService.createOrRestoreForUser(userId);
        return Result.ok(chatSessionService.getDetail(session.getId()));
    }

    @Operation(summary = "我的会话列表")
    @SaCheckLogin
    @GetMapping("/sessions")
    public Result<List<ChatSessionVO>> mySessions() {
        Long userId = StpUtil.getLoginIdAsLong();
        List<ChatSession> list = chatSessionService.listByUser(userId);
        List<ChatSessionVO> vos = list.stream().map(s -> {
            ChatSessionVO vo = chatSessionService.toVO(s);
            vo.setUnreadCount(s.getUserUnread());
            return vo;
        }).toList();
        return Result.ok(vos);
    }

    @Operation(summary = "会话详情")
    @SaCheckLogin
    @GetMapping("/session/{id}")
    public Result<ChatSessionDetailVO> sessionDetail(@PathVariable Long id) {
        return Result.ok(chatSessionService.getDetail(id));
    }

    @Operation(summary = "获取会话历史消息（分页）")
    @SaCheckLogin
    @GetMapping("/session/{id}/messages")
    public Result<List<ChatMessageVO>> messages(
            @PathVariable Long id,
            @RequestParam(required = false) Long afterSeq,
            @RequestParam(defaultValue = "50") int limit) {
        return Result.ok(chatMessageService.getMessages(id, afterSeq, limit));
    }

    @Operation(summary = "发送消息（HTTP 兜底）")
    @SaCheckLogin
    @PostMapping("/session/{id}/message")
    public Result<ChatMessageVO> sendMessage(
            @PathVariable Long id,
            @Valid @RequestBody ChatSendMessageReq req) {
        req.setSessionId(id);
        Long userId = StpUtil.getLoginIdAsLong();
        ChatSession session = chatSessionService.getById(id);
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.fail("会话不存在或无权限");
        }
        return Result.ok(chatMessageService.toVO(
                chatMessageService.sendMessage(req, userId, 0)));
    }

    @Operation(summary = "已读确认")
    @SaCheckLogin
    @PutMapping("/session/{id}/ack")
    public Result<Void> ack(@PathVariable Long id, @Valid @RequestBody ChatAckReq req) {
        req.setSessionId(id);
        chatMessageService.handleAck(req, false);
        return Result.ok();
    }

    @Operation(summary = "关闭会话")
    @SaCheckLogin
    @PutMapping("/session/{id}/close")
    public Result<Void> close(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        ChatSession session = chatSessionService.getById(id);
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.fail("会话不存在或无权限");
        }
        chatSessionService.closeSession(id, userId, false);
        return Result.ok();
    }

    @Operation(summary = "检查客服是否在线")
    @SaCheckLogin
    @GetMapping("/admin/online")
    public Result<Boolean> isAdminOnline() {
        // 简单检测：只要有任意总在线集合中有 admin 成员
        return Result.ok(true); // 返回有用信息依赖于 admin 主动心跳
    }

    @Operation(summary = "在线心跳（用户端延长在线 TTL）")
    @SaCheckLogin
    @PostMapping("/heartbeat")
    public Result<Void> heartbeat() {
        Long userId = StpUtil.getLoginIdAsLong();
        chatOnlineService.markOnline(userId, false);
        return Result.ok();
    }
}
