import logging
from uuid import uuid4

import sys

from pathlib import Path

from rio import App, Theme, Color, Font, ComponentPage, Session
from from_root import from_root

from src.ezgg_lan_manager import pages, init_services, LocalDataService, RefreshService
from src.ezgg_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard
from src.ezgg_lan_manager.services.LocalDataService import LocalData
from src.ezgg_lan_manager.types.UserSession import UserSession

logger = logging.getLogger("EzggLanManager")

if __name__ == "__main__":
    theme = Theme.from_colors(
        primary_color=Color.from_hex("ffffff"),
        secondary_color=Color.from_hex("018786"),
        neutral_color=Color.from_hex("1e1e1e"),
        background_color=Color.from_hex("121212"),
        hud_color=Color.from_hex("02dac5"),
        text_color=Color.from_hex("018786"),
        mode="dark",
        corner_radius_small=0,
        corner_radius_medium=0,
        corner_radius_large=0,
        font=Font(from_root("src/ezgg_lan_manager/assets/fonts/joystix.otf"))
    )
    default_attachments: list = [LocalData(stored_session_token=None)]
    default_attachments.extend(init_services())

    lan_info = default_attachments[3].get_lan_info()

    async def on_session_start(session: Session) -> None:
        # Use this line to fake being any user without having to log in
        # session.attach(UserSession(id=uuid4(), user_id=30, is_team_member=True))
        await session.set_title(lan_info.name)
        session.attach(RefreshService())
        if session[LocalData].stored_session_token:
            user_session = session[LocalDataService].verify_token(session[LocalData].stored_session_token)
            if user_session is not None:
                session.attach(user_session)

    async def on_app_start(a: App) -> None:
        init_result = await a.default_attachments[4].init_db_pool()
        if not init_result:
            logger.fatal("Could not connect to database, exiting...")
            sys.exit(1)

    app = App(
        name="EZGG LAN Manager",
        build=pages.BasePage,
        pages=[
            ComponentPage(
                name="News",
                url_segment="",
                build=pages.NewsPage,
            ),
            ComponentPage(
                name="News",
                url_segment="news",
                build=pages.NewsPage,
            ),
            ComponentPage(
                name="Overview",
                url_segment="overview",
                build=pages.OverviewPage,
            ),
            ComponentPage(
                name="BuyTicket",
                url_segment="buy_ticket",
                build=pages.BuyTicketPage,
            ),
            ComponentPage(
                name="SeatingPlan",
                url_segment="seating",
                build=pages.SeatingPlanPage,
            ),
            ComponentPage(
                name="Catering",
                url_segment="catering",
                build=pages.CateringPage,
            ),
            ComponentPage(
                name="Guests",
                url_segment="guests",
                build=pages.GuestsPage,
            ),
            ComponentPage(
                name="Tournaments",
                url_segment="tournaments",
                build=pages.TournamentsPage,
            ),
            ComponentPage(
                name="FAQ",
                url_segment="faq",
                build=pages.FaqPage,
            ),
            ComponentPage(
                name="RulesGTC",
                url_segment="rules-gtc",
                build=pages.RulesPage
            ),
            ComponentPage(
                name="Contact",
                url_segment="contact",
                build=pages.ContactPage,
            ),
            ComponentPage(
                name="Imprint",
                url_segment="imprint",
                build=pages.ImprintPage,
            ),
            ComponentPage(
                name="Register",
                url_segment="register",
                build=pages.RegisterPage,
                guard=not_logged_in_guard
            ),
            ComponentPage(
                name="ForgotPassword",
                url_segment="forgot-password",
                build=pages.ForgotPasswordPage,
                guard=not_logged_in_guard
            ),
            ComponentPage(
                name="EditProfile",
                url_segment="edit-profile",
                build=pages.EditProfilePage,
                guard=logged_in_guard
            ),
            ComponentPage(
                name="Account",
                url_segment="account",
                build=pages.AccountPage,
                guard=logged_in_guard
            ),
            ComponentPage(
                name="ManageNewsPage",
                url_segment="manage-news",
                build=pages.ManageNewsPage,
                guard=team_guard
            ),
            ComponentPage(
                name="ManageUsersPage",
                url_segment="manage-users",
                build=pages.ManageUsersPage,
                guard=team_guard
            ),
            ComponentPage(
                name="ManageCateringPage",
                url_segment="manage-catering",
                build=pages.ManageCateringPage,
                guard=team_guard
            ),
            ComponentPage(
                name="NewPosOrderPage",
                url_segment="new-pos-order",
                build=pages.NewPosOrderPage,
                guard=team_guard
            ),
            ComponentPage(
                name="ManageTournamentsPage",
                url_segment="manage-tournaments",
                build=pages.ManageTournamentsPage,
                guard=team_guard
            ),
            ComponentPage(
                name="AdminNavigationPage",
                url_segment="admin",
                build=pages.AdminNavigationPage,
                guard=team_guard
            ),
            ComponentPage(
                name="DbErrorPage",
                url_segment="db-error",
                build=pages.DbErrorPage,
            ),
            ComponentPage(
                name="TournamentDetailsPage",
                url_segment="tournament",
                build=pages.TournamentDetailsPage,
            ),
            ComponentPage(
                name="TournamentTreePage",
                url_segment="tournament-tree",
                build=pages.TournamentTreePage,
            ),
            ComponentPage(
                name="TournamentRulesPage",
                url_segment="tournament-rules",
                build=pages.TournamentRulesPage,
            ),
            ComponentPage(
                name="Teams",
                url_segment="teams",
                build=pages.TeamsPage,
            ),
            ComponentPage(
                name="ConwaysGameOfLife",
                url_segment="conway",
                build=pages.ConwayPage,
            )
        ],
        theme=theme,
        assets_dir=Path(__file__).parent / "assets",
        default_attachments=default_attachments,
        on_session_start=on_session_start,
        on_app_start=on_app_start,
        icon=from_root("src/ezgg_lan_manager/assets/img/favicon.png"),
        meta_tags={
            "robots": "INDEX,FOLLOW",
            "description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.",
            "og:description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.",
            "keywords": "Gaming, Clan, Guild, Verein, Club, Einfach, Zocken, Gesellschaft, Videospiele, "
                        "Videogames, LAN, Party, EZ, EZGG, LAN, Manager",
            "author": "David Rodenkirchen",
            "publisher": "EZ GG e.V.",
            "copyright": "EZ GG e.V.",
            "audience": "Alle",
            "page-type": "Management Application",
            "page-topic": "LAN Party",
            "expires": "",
            "revisit-after": "2 days"
        }
    )

    try:
        app.run_as_web_server(
            host="0.0.0.0",
            port=8000,
        )
    except (KeyboardInterrupt, SystemExit):
        logger.info("EZGG LAN Manager was shut down.")
        sys.exit(0)
    except Exception as e:
        logger.error(e)
        sys.exit(1)
