from django.test import Client, RequestFactory, TestCase
from django.utils import timezone  #wjl# 用于处理时间相关的测试

#wjl# 导入 WeRoBot 消息类，用于模拟微信消息
from werobot.messages.messages import TextMessage

#wjl# 导入项目中的模型和 API
from accounts.models import BlogUser           #wjl# 用户模型（用于创建管理员）
from blog.models import Category, Article     #wjl # 博客分类和文章模型
from servermanager.api.commonapi import ChatGPT  #wjl# 聊天功能接口
from .models import commands                  #wjl# 命令模型
from .robot import MessageHandler, CommandHandler  #wjl# 核心机器人处理器
from .robot import search, category, recents   #wjl# 微信机器人命令函数


class ServerManagerTest(TestCase):
    # wjl
    """
    Django 测试用例类，用于对 servermanager 应用的核心功能进行单元测试。
    测试内容包括：
    - ChatGPT 聊天功能
    - 微信机器人命令响应（搜索、分类、最新文章）
    - 服务器命令执行
    - 管理员会话流程
    """

    def setUp(self):
        # wjl
        """
        在每个测试方法执行前自动运行的初始化方法。
        设置测试所需的公共环境：
        - 创建测试客户端（用于模拟 HTTP 请求）
        - 创建请求工厂（用于构造请求对象）

        注意：虽然此处创建了 factory，但在当前测试中并未实际使用。
        """
        self.client = Client()           #wjl# Django 测试客户端
        self.factory = RequestFactory()  #wjl# 请求工厂，用于创建模拟请求

    def test_chat_gpt(self):
        # wjl
        """
        测试 ChatGPT 聊天功能是否正常工作。

        步骤：
        1. 调用 ChatGPT.chat 方法发送问候语 "你好"
        2. 断言返回内容不为 None，表示接口有响应

        目的：验证聊天接口的基本可用性。
        """
        content = ChatGPT.chat("你好")
        self.assertIsNotNone(content)

    def test_validate_comment(self):
        # wjl
        """
        综合测试方法，覆盖多个功能点。
        名称 'validate_comment' 不准确，实际测试的是 servermanager 的核心功能。

        测试流程：
        1. 创建管理员用户并登录
        2. 创建分类和文章用于测试搜索功能
        3. 测试微信机器人的 search、category、recents 命令
        4. 测试命令执行（CommandHandler）
        5. 模拟完整管理员会话流程（登录、执行命令、退出等）
        """

        #wjl # 1. 创建超级用户
        user = BlogUser.objects.create_superuser(
            email="liangliangyy1@gmail.com",
            username="liangliangyy1",
            password="liangliangyy1")

        #wjl# 使用测试客户端登录该用户
        self.client.login(username='liangliangyy1', password='liangliangyy1')

        #wjl# 2. 创建博客分类
        c = Category()
        c.name = "categoryccc"
        c.save()

        #wjl# 3. 创建一篇已发布的文章
        article = Article()
        article.title = "nicetitleccc"
        article.body = "nicecontentccc"
        article.author = user
        article.category = c
        article.type = 'a'  #wjl# 文章类型
        article.status = 'p' #wjl # 发布状态
        article.save()

        #wjl# 4. 模拟微信文本消息
        s = TextMessage([])
        s.content = "nice"  #wjl# 搜索关键词

        #wjl # 5. 测试 search 命令
        #wjlrsp = search(s, None)  # 调用 search 过滤器
        #wjl # 断言有响应（即使未找到文章也应返回提示）

        #wjl # 6. 测试 category 命令
        rsp = category(None, None)
        self.assertIsNotNone(rsp)  # 确保返回了分类列表

        #wjl# 7. 测试 recents 命令
        rsp = recents(None, None)
        #wjl# 断言返回结果不是“暂时还没有文章”，说明能获取到文章
        self.assertTrue(rsp != '暂时还没有文章')

        #wjl # 8. 测试命令执行功能
        cmd = commands()
        cmd.title = "test"
        cmd.command = "ls"      #wjl # 测试命令（列出目录）
        cmd.describe = "test"
        cmd.save()              #wjl # 保存到数据库

        #wjl# 实例化命令处理器
        cmdhandler = CommandHandler()
        #wjl  # 执行名为 'test' 的命令
        rsp = cmdhandler.run('test')
        #wjl# 断言命令执行有返回结果
        self.assertIsNotNone(rsp)

        #wjl# 9. 模拟管理员会话流程
        s.source = 'u'  #wjl# 设置用户标识（OpenID）
        s.content = 'test' #wjl # 用户输入内容

        #wjl# 创建消息处理器实例，传入模拟消息和空会话
        msghandler = MessageHandler(s, {})

        #wjl# 模拟用户行为序列：
        msghandler.handler()  #wjl# 处理 "test" 消息（应提示确认）

        s.content = 'y'  #wjl# 用户确认执行
        msghandler.handler()  #wjl# 执行命令

        s.content = 'idcard:12321233'  #wjl# 尝试身份证查询（占位功能）
        msghandler.handler()

        s.content = 'weather:上海'  #wjl# 尝试天气查询（占位功能）
        msghandler.handler()

        s.content = 'admin'  #wjl# 请求进入管理员模式
        msghandler.handler()

        s.content = '123'  #wjl# 输入密码（测试环境下有效）
        msghandler.handler()

        s.content = 'exit' #wjl # 退出管理员模式
        msghandler.handler()

        #wjl# 注意：此测试未包含 assert 断言来验证每个步骤的结果，
        #wjl# 主要是通过调用来检查是否抛出异常，确保代码路径可执行。