import sys
from datetime import datetime
from decimal import Decimal
from pathlib import Path
import logging
import tomllib

from from_root import from_root

from src.ezgg_lan_manager.types.ConfigurationTypes import DatabaseConfiguration, MailingServiceConfiguration, LanInfo, \
    SeatingConfiguration, TicketInfo, ReceiptPrintingConfiguration

logger = logging.getLogger(__name__.split(".")[-1])


class ConfigurationService:
    def __init__(self, config_file_path: Path) -> None:
        try:
            with open(from_root("VERSION"), "r") as version_file:
                self._version = version_file.read().strip()
        except FileNotFoundError:
            logger.warning("Could not find VERSION file, defaulting to '0.0.0'")
            self._version = "0.0.0"

        try:
            with open(config_file_path, "rb") as config_file:
                self._config = tomllib.load(config_file)
        except FileNotFoundError:
            logger.fatal(f"Could not find config file at \"{config_file_path}\", exiting...")
            exit(1)

    def get_database_configuration(self) -> DatabaseConfiguration:
        try:
            database_configuration = self._config["database"]
            return DatabaseConfiguration(
                db_user=database_configuration["db_user"],
                db_password=database_configuration["db_password"],
                db_host=database_configuration["db_host"],
                db_port=database_configuration["db_port"],
                db_name=database_configuration["db_name"]
            )
        except KeyError:
            logger.fatal("Error loading DatabaseConfiguration, exiting...")
            sys.exit(1)

    def get_mailing_service_configuration(self) -> MailingServiceConfiguration:
        try:
            mailing_configuration = self._config["mailing"]
            return MailingServiceConfiguration(
                smtp_server=mailing_configuration["smtp_server"],
                smtp_port=mailing_configuration["smtp_port"],
                sender=mailing_configuration["sender"],
                username=mailing_configuration["username"],
                password=mailing_configuration["password"]
            )
        except KeyError:
            logger.fatal("Error loading MailingServiceConfiguration, exiting...")
            sys.exit(1)

    def get_lan_info(self) -> LanInfo:
        try:
            lan_info = self._config["lan"]
            return LanInfo(
                name=lan_info["name"],
                iteration=lan_info["iteration"],
                date_from=datetime.strptime(lan_info["date_from"], "%Y-%m-%d %H:%M:%S"),
                date_till=datetime.strptime(lan_info["date_till"], "%Y-%m-%d %H:%M:%S"),
                organizer_mail=lan_info["organizer_mail"]
            )
        except KeyError:
            logger.fatal("Error loading LAN Info, exiting...")
            sys.exit(1)

    def get_ticket_info(self) -> tuple[TicketInfo, ...]:
        try:
            return tuple([TicketInfo(
                category=value,
                total_tickets=self._config["tickets"][value]["total_tickets"],
                price=Decimal(self._config["tickets"][value]["price"]),
                description=self._config["tickets"][value]["description"],
                additional_info=self._config["tickets"][value]["additional_info"],
                is_default=self._config["tickets"][value]["is_default"]
            ) for value in self._config["tickets"]])
        except KeyError as e:
            logger.debug(e)
            logger.fatal("Error loading seating configuration, exiting...")
            sys.exit(1)

    def get_receipt_printing_configuration(self) -> ReceiptPrintingConfiguration:
        try:
            receipt_printing_configuration = self._config["receipt_printing"]
            return ReceiptPrintingConfiguration(
                host=receipt_printing_configuration["host"],
                port=receipt_printing_configuration["port"],
                order_print_endpoint=receipt_printing_configuration["order_print_endpoint"],
                password=receipt_printing_configuration["password"]
            )
        except KeyError:
            logger.fatal("Error loading Receipt Printing Configuration, exiting...")
            sys.exit(1)

    @property
    def APP_VERSION(self) -> str:
        return self._version

    @property
    def DEV_MODE_ACTIVE(self) -> bool:
        return self._config["misc"]["dev_mode_active"]
