from extensions import db, login_manager
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


class User(UserMixin, db.Model):
    __tablename__ = 'users'

    id         = db.Column(db.Integer, primary_key=True)
    nama       = db.Column(db.String(100), nullable=False)
    email      = db.Column(db.String(120), unique=True, nullable=False)
    password   = db.Column(db.String(255), nullable=False)
    role       = db.Column(db.Enum('admin', 'user'), default='user', nullable=False)
    status     = db.Column(db.Enum('aktif', 'nonaktif'), default='aktif', nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    predictions = db.relationship('Prediction', backref='user', lazy=True)

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password, password)

    def __repr__(self):
        return f'<User {self.email}>'


class ModelInfo(db.Model):
    __tablename__ = 'model_info'

    id          = db.Column(db.Integer, primary_key=True)
    nama_model  = db.Column(db.String(100), nullable=False)   # 'IndoBERT' / 'Naive Bayes'
    tipe        = db.Column(db.String(50), nullable=False)     # 'indobert' / 'naive_bayes'
    accuracy    = db.Column(db.Float)
    precision   = db.Column(db.Float)
    recall      = db.Column(db.Float)
    f1_score    = db.Column(db.Float)
    path_folder = db.Column(db.String(255))
    is_default  = db.Column(db.Boolean, default=False)
    created_at  = db.Column(db.DateTime, default=datetime.utcnow)

    def __repr__(self):
        return f'<ModelInfo {self.nama_model}>'


class Prediction(db.Model):
    __tablename__ = 'predictions'

    id            = db.Column(db.Integer, primary_key=True)
    user_id       = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    komentar      = db.Column(db.Text, nullable=False)
    label_hasil   = db.Column(db.Enum('Positif', 'Negatif', 'Netral'), nullable=False)
    confidence    = db.Column(db.Float)
    prob_positif  = db.Column(db.Float)
    prob_negatif  = db.Column(db.Float)
    prob_netral   = db.Column(db.Float)
    model_dipakai = db.Column(db.String(50))   # 'indobert' / 'naive_bayes'
    tipe_input    = db.Column(db.Enum('manual', 'bulk'), default='manual')
    created_at    = db.Column(db.DateTime, default=datetime.utcnow)

    def __repr__(self):
        return f'<Prediction {self.id} - {self.label_hasil}>'


class WordCount(db.Model):
    __tablename__ = 'word_count'

    id               = db.Column(db.Integer, primary_key=True)
    kata             = db.Column(db.String(100), nullable=False)
    frekuensi        = db.Column(db.Integer, default=0)
    sentimen_dominan = db.Column(db.Enum('Positif', 'Negatif', 'Netral'))
    pct_positif      = db.Column(db.Float, default=0)
    pct_negatif      = db.Column(db.Float, default=0)
    pct_netral       = db.Column(db.Float, default=0)

    def __repr__(self):
        return f'<WordCount {self.kata}>'
