"""
SQLAlchemy ORM models — Son of Anton v4.0
"""

from datetime import datetime, timedelta
from uuid import uuid4

from sqlalchemy import (
    Column, String, Text, Boolean, BigInteger, Integer, DateTime, ForeignKey,
)
from sqlalchemy.orm import relationship

from backend.database import Base


def new_id() -> str:
    return str(uuid4())


def next_month() -> datetime:
    now = datetime.utcnow()
    if now.month == 12:
        return datetime(now.year + 1, 1, 1)
    return datetime(now.year, now.month + 1, 1)


class User(Base):
    __tablename__ = "users"

    id = Column(String(36), primary_key=True, default=new_id)
    username = Column(String(50), unique=True, nullable=False, index=True)
    email = Column(String(120), unique=True, nullable=False)
    password_hash = Column(String(200), nullable=False)
    role = Column(String(20), default="user")
    is_active = Column(Boolean, default=True)
    quota_tokens_monthly = Column(BigInteger, default=2_000_000)
    tokens_used_this_month = Column(BigInteger, default=0)
    quota_reset_date = Column(DateTime, default=next_month)
    created_at = Column(DateTime, default=datetime.utcnow)

    chats = relationship("Chat", back_populates="user", cascade="all,delete-orphan")


class Chat(Base):
    __tablename__ = "chats"

    id = Column(String(36), primary_key=True, default=new_id)
    user_id = Column(String(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
    title = Column(String(200), default="New Chat")
    model = Column(String(100), default="eu.anthropic.claude-opus-4-6-v1")
    knowledge_base_id = Column(String(36), nullable=True)
    gitlab_project_id = Column(Integer, nullable=True)
    gitlab_branch = Column(String(200), nullable=True, default="main")
    max_tokens = Column(Integer, default=4096)
    reasoning_budget = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    user = relationship("User", back_populates="chats")
    messages = relationship(
        "Message", back_populates="chat",
        cascade="all,delete-orphan", order_by="Message.created_at",
    )
    attachments = relationship(
        "ChatAttachment", back_populates="chat",
        cascade="all,delete-orphan",
    )


class Message(Base):
    __tablename__ = "messages"

    id = Column(String(36), primary_key=True, default=new_id)
    chat_id = Column(String(36), ForeignKey("chats.id", ondelete="CASCADE"), nullable=False)
    role = Column(String(20), nullable=False)
    content = Column(Text, default="")
    thinking_content = Column(Text, nullable=True)
    input_tokens = Column(Integer, default=0)
    output_tokens = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)

    chat = relationship("Chat", back_populates="messages")
    attachments = relationship("ChatAttachment", back_populates="message")


class ChatAttachment(Base):
    __tablename__ = "chat_attachments"

    id = Column(String(36), primary_key=True, default=new_id)
    chat_id = Column(String(36), ForeignKey("chats.id", ondelete="CASCADE"), nullable=False)
    message_id = Column(String(36), ForeignKey("messages.id", ondelete="SET NULL"), nullable=True)
    filename = Column(String(200), nullable=False)
    original_filename = Column(String(200), nullable=False)
    mime_type = Column(String(100), nullable=False)
    file_type = Column(String(20), nullable=False)
    file_size = Column(Integer, default=0)
    storage_path = Column(String(500), nullable=False)
    text_extract = Column(Text, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)

    chat = relationship("Chat", back_populates="attachments")
    message = relationship("Message", back_populates="attachments")


class KnowledgeBase(Base):
    __tablename__ = "knowledge_bases"

    id = Column(String(36), primary_key=True, default=new_id)
    user_id = Column(String(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=True)
    name = Column(String(200), nullable=False)
    description = Column(Text, default="")
    document_count = Column(Integer, default=0)
    chunk_count = Column(Integer, default=0)
    total_characters = Column(BigInteger, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)


class KnowledgeDocument(Base):
    __tablename__ = "knowledge_documents"

    id = Column(String(36), primary_key=True, default=new_id)
    knowledge_base_id = Column(
        String(36), ForeignKey("knowledge_bases.id", ondelete="CASCADE"), nullable=False,
    )
    filename = Column(String(200), nullable=False)
    file_size = Column(Integer, default=0)
    chunk_count = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)


# ══════════════════════════════════════════════════════
#  GitLab CE Integration Models
# ══════════════════════════════════════════════════════

class GitLabConfig(Base):
    __tablename__ = "gitlab_configs"

    id = Column(String(36), primary_key=True, default=new_id)
    gitlab_url = Column(String(500), nullable=False)
    access_token_enc = Column(String(500), nullable=False)
    default_namespace = Column(String(200), nullable=True)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)


class GitLabOperation(Base):
    __tablename__ = "gitlab_operations"

    id = Column(String(36), primary_key=True, default=new_id)
    operation_type = Column(String(50), nullable=False)
    status = Column(String(20), default="pending")
    project_id = Column(Integer, nullable=True)
    project_name = Column(String(200), nullable=True)
    branch = Column(String(200), nullable=True)
    payload = Column(Text, nullable=False)
    result = Column(Text, nullable=True)
    chat_id = Column(String(36), nullable=True)
    message_id = Column(String(36), nullable=True)
    created_by = Column(String(36), ForeignKey("users.id"), nullable=False)
    approved_by = Column(String(36), nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    executed_at = Column(DateTime, nullable=True)


class GitLabAuditLog(Base):
    __tablename__ = "gitlab_audit_log"

    id = Column(String(36), primary_key=True, default=new_id)
    operation_id = Column(String(36), nullable=True)
    action = Column(String(100), nullable=False)
    details = Column(Text, nullable=True)
    user_id = Column(String(36), nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)