from django.db import models
from userapp.models import ParadiseUser


class Bot(models.Model):
    name = models.CharField(max_length=255, verbose_name='机器人姓名')
    description = models.TextField(blank=False, null=False, verbose_name='机器人提示词')

    class Meta:
        verbose_name = '机器人'
        verbose_name_plural = '机器人'

    def __str__(self):
        return self.name

class ChatMessage(models.Model):
    SENDER_USER = 'user'
    SENDER_BOT = 'assistant'
    SENDER_SYSTEM = 'system'

    SENDER_CHOICES = [
        (SENDER_USER, 'user'),
        (SENDER_BOT, 'assistant'),
        (SENDER_SYSTEM, 'system'),
    ]

    MESSAGE_TYPE_TEXT = 'text'
    MESSAGE_TYPE_AUDIO = 'audio'
    MESSAGE_TYPE_VIDEO = 'video'

    MESSAGE_TYPE_CHOICES = [
        (MESSAGE_TYPE_TEXT, 'text'),
        (MESSAGE_TYPE_AUDIO, 'audio'),
        (MESSAGE_TYPE_VIDEO, 'video'),
    ]

    user = models.ForeignKey(ParadiseUser, on_delete=models.CASCADE, verbose_name='用户')
    bot = models.ForeignKey(Bot, on_delete=models.CASCADE, verbose_name='机器人')
    message = models.TextField(max_length=2048, null=False, blank=False, verbose_name='消息内容')
    message_audio_url = models.TextField(max_length=2048, blank=True, verbose_name='消息内容语音链接')
    message_video_url = models.TextField(max_length=2048, blank=True, verbose_name='消息内容视频链接')
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='时间戳')
    sender = models.CharField(max_length=10, choices=SENDER_CHOICES, verbose_name='发送者')
    message_type = models.CharField(max_length=10, choices=MESSAGE_TYPE_CHOICES, default=MESSAGE_TYPE_TEXT, verbose_name='消息类型')

    class Meta:
        ordering = ['timestamp']  # 按时间顺序排序
        verbose_name = '聊天消息'
        verbose_name_plural = '聊天消息'

    def __str__(self):
        return f"{self.sender}: {self.message[:50]} ({self.timestamp})"


class CredentialSlot(models.Model):
    """通用凭据槽位（单例）— Milestone v1.0 / Phase 1

    全局唯一一条记录，存第三方服务（Kimi / 阿里云 / 火山等）的 APP ID + Access Token。
    通过 pk=1 + get_or_create + save() 钩子三件套保证单例：
        - 任何 .save() 在已有记录时把新对象 pk 改成现有那条
        - get_solo() 是单一访问入口（Phase 2/3 视图统一调用）
        - DB 层无额外约束，绕过 ORM 的 bulk_create / 原始 SQL 不在保护范围
    """

    app_id = models.CharField(
        'APP ID', max_length=128, blank=True, default='',
        help_text='第三方服务商分配的 APP ID；运营在 Admin 录入'
    )
    access_token = models.CharField(
        'Access Token', max_length=512, blank=True, default='',
        help_text='第三方服务商访问令牌；DB 明文存储，Admin 列表/查看态末 4 位脱敏'
    )
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    class Meta:
        verbose_name = '凭据槽位'
        verbose_name_plural = '凭据槽位'

    def __str__(self):
        return f"凭据槽位 (updated {self.updated_at:%Y-%m-%d %H:%M})"

    def save(self, *args, **kwargs):
        # 强制单例：新增时如果已有记录则覆盖到现有 pk
        if not self.pk and CredentialSlot.objects.exists():
            existing = CredentialSlot.objects.first()
            self.pk = existing.pk
        super().save(*args, **kwargs)

    @classmethod
    def get_solo(cls):
        """获取单例实例，不存在则用默认值创建（pk=1）"""
        instance, _ = cls.objects.get_or_create(pk=1)
        return instance