from __future__ import annotations
import datetime

from typing import Optional
import sqlalchemy
from sqlalchemy import select, update
from sqlalchemy.orm import mapped_column, Mapped

from api.model.base import BaseModel
from service.database import DatabaseService


class PageTitleModel(BaseModel):
    __tablename__ = "toolkit_ui_page_title"

    id: Mapped[int] = mapped_column(
        sqlalchemy.Integer, primary_key=True, autoincrement=True)
    page_id: Mapped[int] = mapped_column(sqlalchemy.Integer, index=True)
    title: Mapped[str] = mapped_column(sqlalchemy.String(255), nullable=True)
    updated_at: Mapped[int] = mapped_column(
        sqlalchemy.TIMESTAMP, index=True, server_default=sqlalchemy.func.now())


class PageTitleHelper:
    def __init__(self, dbs: DatabaseService):
        self.dbs = dbs
        self.initialized = False

    async def __aenter__(self):
        if not self.initialized:
            self.create_session = self.dbs.create_session
            self.session = self.dbs.create_session()
            await self.session.__aenter__()

            self.initialized = True

        return self

    async def __aexit__(self, exc_type, exc, tb):
        await self.session.__aexit__(exc_type, exc, tb)
        pass

    async def find_by_page_id(self, page_id: int):
        stmt = select(PageTitleModel).where(PageTitleModel.page_id == page_id)
        return await self.session.scalar(stmt)

    async def find_by_title(self, title: str):
        stmt = select(PageTitleModel).where(PageTitleModel.title == title)
        return await self.session.scalar(stmt)

    async def get_page_id_by_title(self, title: str):
        obj = await self.find_by_title(title)
        if obj is None:
            return None
        return obj.page_id

    async def should_update(self, title: str):
        title_info = await self.find_by_title(title)
        if title_info is None:
            return True
        if title_info.updated_at < (datetime.now() - datetime.timedelta(days=7)):
            return True

    async def add(self, page_id: int, title: Optional[str] = None):
        obj = PageTitleModel(page_id=page_id, title=title, updated_at=sqlalchemy.func.current_timestamp())

        self.session.add(obj)
        await self.session.commit()
        await self.session.refresh(obj)
        return obj

    async def set_title(self, page_id: int, title: Optional[str] = None):
        stmt = update(PageTitleModel).where(
            PageTitleModel.page_id == page_id).values(title=title, updated_at=sqlalchemy.func.current_timestamp())
        await self.session.execute(stmt)
        await self.session.commit()

    async def update(self, obj: PageTitleModel, ignore_updated_at: bool = False):
        self.session.merge(obj)
        if not ignore_updated_at:
            obj.updated_at = sqlalchemy.func.current_timestamp()
        await self.session.commit()
        await self.session.refresh(obj)
        return obj