import logging
import os
from datetime import datetime as dt

from sqlmodel import Field, Session, SQLModel, create_engine, select, text

## Todo List
# - [ ] add to fridge
# - [ ] reminder to eat recent food
# - [ ] reminder to toss old food

DATE_FORMAT = '%A, %Y-%m-%d'
MODULE='fridge'
STALE_DAYS = 2
TOSS_DAYS = 4

def today():
    return dt.now().strftime(DATE_FORMAT)

logger = logging.getLogger(__name__)
logging.basicConfig(filename=f'{MODULE}.log', encoding='utf-8', level=logging.DEBUG)

class Food(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    name: str = Field(default=None, unique=True)
    added_date: dt = Field(default_factory=lambda: dt.now())

    def __str__(self):
        added = self.added_date.strftime(DATE_FORMAT)
        return f'{self.name} ({added})'

class Data():
    def __init__(self, db_file):

        self.file = db_file
        self.engine = self.get_engine()

    def get_db_file(self):
        return self.file

    def get_engine(self):
        return create_engine(f"sqlite:///{self.file}")

    def setup(self):
        SQLModel.metadata.create_all(self.engine)

    @staticmethod
    def get_stale():
        return dt.now() - dt.timedelta(STALE_DAYS)

    def list(self):
        results = []
        with Session(self.engine) as session:
            stale_dt = Data.get_stale()
            cmd = select(Food).where(Food.added_date < stale_dt)
            results = session.exec(cmd).all()
            if(not results):
                results.append('Nothing Found')

        return results

    def to_toss(self):
        results = []
        with Session(self.engine) as session:
            stale_dt = Data.get_stale()
            cmd = select(Food).where(Food.added_date >= stale_dt)
            results = session.exec(cmd).all()
            if(not results):
                results.append('Nothing Found')

        return results


    def filter(self, term):
        results = []
        for item in self.list():
            if term in item:
                results.append(item)

        return results
        
    def add(self, name):
        try:
            with Session(self.engine) as session:
                new = Food(name=name)
                session.add(new)
                session.commit()
            return f'Added {name}.'
        except:
            return f'Unable to add {name}. May be duplicate.'

    @staticmethod
    def get_food(session, food):
        cmd = select(Food).filter(Food.name.ilike(f'%{food}%'))
        return session.exec(cmd).one()

    def remove(self, name):
        # TODO: Tag as tossed or eaten
        with Session(self.engine) as session:
            item  = Data.get_food(session, name)
            if(not item):
                return f'Not found: {name}'

            try:
                name = item.name
                session.remove(item)
                session.commit()
                return f'Removed item {name}'
            except Exception as ex:
                return f'Unable to remove item mark chore as done: {ex}'


