from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from datetime import datetime
import json

from extensions import db

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    discord_id = db.Column(db.String(50), unique=True, nullable=False)
    username = db.Column(db.String(100), nullable=False)
    minecraft_uuid = db.Column(db.String(36), unique=True, nullable=True)
    minecraft_username = db.Column(db.String(16), nullable=True)
    is_admin = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class Event(db.Model):
    __tablename__ = 'events'
    id = db.Column(db.Integer, primary_key=True)
    event_type = db.Column(db.String(50), nullable=False) # CHAT, JOIN, QUIT, DEATH, TELEPORT
    player_uuid = db.Column(db.String(36), nullable=True)
    player_name = db.Column(db.String(16), nullable=True)
    content = db.Column(db.Text, nullable=True) # Chat message, death message, etc.
    location = db.Column(db.String(100), nullable=True) # Serialized location
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

    def to_dict(self):
        return {
            'type': self.event_type,
            'player': self.player_name,
            'uuid': self.player_uuid,
            'content': self.content,
            'location': self.location,
            'timestamp': self.timestamp.isoformat() if self.timestamp else None,
            'inventory': json.loads(self.inventory.items) if self.inventory else None
        }

class EventConfig(db.Model):
    __tablename__ = 'event_configs'
    event_name = db.Column(db.String(255), primary_key=True) # Full class name
    package_name = db.Column(db.String(255), nullable=False)
    is_enabled = db.Column(db.Boolean, default=True)

class Inventory(db.Model):
    __tablename__ = 'inventories'
    id = db.Column(db.Integer, primary_key=True)
    event_id = db.Column(db.Integer, db.ForeignKey('events.id'), nullable=False)
    player_uuid = db.Column(db.String(36), nullable=False)
    items = db.Column(db.Text, nullable=False) # JSON serialized inventory
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
    
    event = db.relationship('Event', backref=db.backref('inventory', uselist=False))

class Ticket(db.Model):
    __tablename__ = 'tickets'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) # Creator
    title = db.Column(db.String(200), nullable=False)
    description = db.Column(db.Text, nullable=False)
    status = db.Column(db.String(20), default='OPEN') # OPEN, CLOSED, IN_PROGRESS
    closing_reason = db.Column(db.Text, nullable=True)
    closed_by_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    creator = db.relationship('User', backref='created_tickets', foreign_keys=[user_id])
    closed_by = db.relationship('User', foreign_keys=[closed_by_id])
    assignments = db.relationship('TicketAssignment', backref='ticket', cascade="all, delete-orphan")
    comments = db.relationship('TicketComment', backref='ticket', cascade="all, delete-orphan", order_by='TicketComment.created_at')

class TicketAssignment(db.Model):
    __tablename__ = 'ticket_assignments'
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id'), primary_key=True)
    assigned_at = db.Column(db.DateTime, default=datetime.utcnow)

    user = db.relationship('User', backref='assignments')

class TicketComment(db.Model):
    __tablename__ = 'ticket_comments'
    id = db.Column(db.Integer, primary_key=True)
    ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    content = db.Column(db.Text, nullable=False)
    is_hidden = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    user = db.relationship('User', backref='comments')

class LinkCode(db.Model):
    __tablename__ = 'link_codes'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    code = db.Column(db.String(10), unique=True, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    expires_at = db.Column(db.DateTime, nullable=False)

    user = db.relationship('User', backref=db.backref('link_code', uselist=False, cascade="all, delete-orphan"))

class Application(db.Model):
    __tablename__ = 'applications'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    position = db.Column(db.String(50), nullable=False) # MODERATOR, DEVELOPER
    content = db.Column(db.Text, nullable=False)
    status = db.Column(db.String(20), default='PENDING') # PENDING, ACCEPTED, REJECTED
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    user = db.relationship('User', backref='applications')
