import logging
from pathlib import Path

from watchfiles import awatch

from app.context.context import Context
from app.settings import Contacts, Prompt, Settings

logger = logging.getLogger(__name__)


async def watch_files_and_sync_states(ctx: Context) -> None:
    ctx.contacts.subscribe(lambda c: c.persist(ctx.paths.contacts_path))

    settings_path = ctx.paths.settings_path
    prompt_path = ctx.paths.prompt_path
    contacts_path = ctx.paths.contacts_path

    relevant_files = {settings_path, prompt_path, contacts_path}

    def watch_filter(_change: object, raw_path: str) -> bool:
        path = Path(raw_path)
        return path in relevant_files

    async for changes in awatch(str(ctx.paths.base_dir), watch_filter=watch_filter):
        for _change_type, raw_path in changes:
            path = Path(raw_path)

            if path == settings_path:
                ctx.settings.set(Settings.load(settings_path))
                ctx.settings.get().ensure_environment_variables()
            elif path == prompt_path:
                ctx.prompt.set(Prompt.load(prompt_path))
            elif path == contacts_path:
                ctx.contacts.set(Contacts.load(contacts_path))

            logger.debug("%s recarregado pelo Watcher", path.name)
