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

db = SQLAlchemy()


class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    runs = db.relationship('AnalysisRun', backref='user', lazy=True)


class AnalysisRun(db.Model):
    __tablename__ = 'analysis_runs'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    filename = db.Column(db.String(255), nullable=False)
    test_size = db.Column(db.Float, nullable=False)
    accuracy = db.Column(db.Float)
    total_data = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    datasets = db.relationship('Dataset', backref='run', lazy=True)
    metrics = db.relationship('ClassificationMetric', backref='run', lazy=True)
    confusion_matrix = db.relationship('ConfusionMatrix', backref='run', lazy=True)
    preprocessing_logs = db.relationship('PreprocessingLog', backref='run', lazy=True)


class Dataset(db.Model):
    __tablename__ = 'datasets'
    id = db.Column(db.Integer, primary_key=True)
    run_id = db.Column(db.Integer, db.ForeignKey('analysis_runs.id'), nullable=False)
    sentimen_asli = db.Column(db.Text)
    score = db.Column(db.Integer)
    label = db.Column(db.String(20))
    case_folded = db.Column(db.Text)
    cleaned = db.Column(db.Text)
    tokenized = db.Column(db.Text)
    stopword_removed = db.Column(db.Text)
    stemmed = db.Column(db.Text)


class ClassificationMetric(db.Model):
    __tablename__ = 'classification_metrics'
    id = db.Column(db.Integer, primary_key=True)
    run_id = db.Column(db.Integer, db.ForeignKey('analysis_runs.id'), nullable=False)
    label = db.Column(db.String(20), nullable=False)
    precision = db.Column(db.Float)
    recall = db.Column(db.Float)
    f1_score = db.Column(db.Float)
    support = db.Column(db.Integer)


class ConfusionMatrix(db.Model):
    __tablename__ = 'confusion_matrix'
    id = db.Column(db.Integer, primary_key=True)
    run_id = db.Column(db.Integer, db.ForeignKey('analysis_runs.id'), nullable=False)
    actual_label = db.Column(db.String(20), nullable=False)
    predicted_label = db.Column(db.String(20), nullable=False)
    count = db.Column(db.Integer)


class PreprocessingLog(db.Model):
    __tablename__ = 'preprocessing_logs'
    id = db.Column(db.Integer, primary_key=True)
    run_id = db.Column(db.Integer, db.ForeignKey('analysis_runs.id'), nullable=False)
    tahap = db.Column(db.String(50), nullable=False)
    jumlah_sebelum = db.Column(db.Integer)
    jumlah_sesudah = db.Column(db.Integer)
    waktu_proses = db.Column(db.Float)
