import json
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
from app import db


def get_local_now():
    return datetime.now(ZoneInfo("America/New_York")).replace(tzinfo=None)


class Article(db.Model):
    __tablename__ = "articles"

    id = db.Column(db.Integer, primary_key=True)
    guid = db.Column(db.Text, unique=True, nullable=False)
    title = db.Column(db.Text, nullable=False)
    author = db.Column(db.Text, nullable=False)
    pub_date = db.Column(db.DateTime, nullable=False)
    categories = db.Column(db.Text, nullable=False, default="[]")
    link = db.Column(db.Text, nullable=False)
    content_html = db.Column(db.Text, nullable=False, default="")
    fetched_at = db.Column(
        db.DateTime, nullable=False, default=get_local_now
    )

    images = db.relationship("Image", backref="article", lazy=True,
                             cascade="all, delete-orphan")


class Image(db.Model):
    __tablename__ = "images"

    id = db.Column(db.Integer, primary_key=True)
    article_id = db.Column(db.Integer, db.ForeignKey("articles.id"), nullable=False)
    original_url = db.Column(db.Text, nullable=False)
    local_path = db.Column(db.Text, nullable=False)
    width = db.Column(db.Integer, nullable=False)
    height = db.Column(db.Integer, nullable=False)


class Issue(db.Model):
    __tablename__ = "issues"

    id = db.Column(db.Integer, primary_key=True)
    week_start = db.Column(db.Date, nullable=False)
    week_end = db.Column(db.Date, nullable=False)
    cover_method = db.Column(db.Text, nullable=False)
    cover_path = db.Column(db.Text, nullable=False)
    epub_path = db.Column(db.Text, nullable=False)
    article_ids = db.Column(db.Text, nullable=False, default="[]")
    excluded_article_ids = db.Column(db.Text, nullable=False, default="[]")
    created_at = db.Column(
        db.DateTime, nullable=False, default=get_local_now
    )
    status = db.Column(db.Text, nullable=False, default="draft")
    issue_type = db.Column(db.Text, nullable=False, default="weekly")


class Setting(db.Model):
    __tablename__ = "settings"

    key = db.Column(db.Text, primary_key=True)
    value = db.Column(db.Text, nullable=False)

    @staticmethod
    def get(key, default=None):
        row = db.session.get(Setting, key)
        if row is None:
            return default
        return json.loads(row.value)

    @staticmethod
    def set(key, value):
        row = db.session.get(Setting, key)
        if row is None:
            row = Setting(key=key, value=json.dumps(value))
            db.session.add(row)
        else:
            row.value = json.dumps(value)
        db.session.commit()
