from aiohttp import web
from smb.common.multiruntime.lib.io import setup_filesystem

from maps_adv.common.avatars import AvatarsClient
from maps_adv.common.lasagna import Lasagna
from maps_adv.common.ugcdb_client import UgcdbClient
from maps_adv.geosmb.clients.bunker import BunkerClient
from maps_adv.geosmb.clients.bvm import BvmClient
from maps_adv.geosmb.clients.geobase import GeoBaseClient
from maps_adv.geosmb.clients.geosearch import GeoSearchClient
from maps_adv.geosmb.clients.market import MarketIntClient
from maps_adv.geosmb.tuner.client import TunerClient

from . import api, tasks
from .async_yt_client import AsyncYtClient
from .data_manager import BaseDataManager, DataManager
from .db import DB
from .domain import Domain
from .ext_feed_lb_writer import ExtFeedLogbrokerWriter

setup_filesystem("maps_adv/geosmb/landlord/server/")


class Application(Lasagna):
    __slots__ = ("dm", "domain")
    SWIM_ENGINE_CLS = DB

    TASKS_KWARGS_KEYS = ["dm", "domain", "config"]
    TASKS = {
        "geosmb_landlord__import_promo_from_yt": tasks.ImportPromosTask,
        "geosmb_landlord__import_promoted_cta_from_yt": tasks.ImportPromotedCtaTask,
        "geosmb_landlord__import_promoted_service_lists_from_yt": tasks.ImportPromotedServiceListsTask,  # noqa
        "geosmb_landlord__import_promoted_services_from_yt": tasks.ImportPromotedServicesTask,  # noqa
        "geosmb_landlord__import_call_tracking_from_yt": tasks.ImportCallTrackingTask,
        "geosmb_landlord__update_landing_config_from_bunker": tasks.update_landing_config_from_bunker,  # noqa
        "geosmb_landlord__import_google_counters_from_yt": tasks.ImportGoogleCountersTask,  # noqa
        "geosmb_landlord__import_avatars_from_yt": tasks.ImportAvatarsTask,
        "geosmb_landlord__import_geosearch_data": tasks.update_geosearch_data,
        "geosmb_landlord__push_landing_urls_to_ext_feed_lb": tasks.push_landing_urls_to_ext_feed_lb,  # noqa
        "geosmb_landlord__import_market_int_services_from_yt": tasks.ImportMarketIntServicesTask,  # noqa
        "geosmb_landlord__import_tiktok_pixels_from_yt": tasks.ImportTikTokPixelsTask,  # noqa
        "geosmb_landlord__import_goods_data_from_yt": tasks.ImportGoodsDataTask,
        "geosmb_landlord__import_vk_pixels_from_yt": tasks.ImportVkPixelsTask,
        "geosmb_landlord__sync_permalinks_from_yt": tasks.SyncPermalinksTask,
    }

    dm: BaseDataManager
    domain: Domain

    async def _setup_layers(self, db: DB) -> web.Application:
        self.dm = DataManager(db)

        clients = await self._setup_clients()
        self.domain = Domain(
            dm=self.dm,
            config=self.config,
            fetch_data_token=self.config["FETCH_DATA_TOKEN"],
            **clients,
            base_maps_url=self.config["BASE_MAPS_URL"],
            base_widget_request_url=self.config["BASE_WIDGET_REQUEST_URL"],
            avatars_upload_timeout=self.config["AVATARS_UPLOAD_TIMEOUT"],
            disable_promoted_services=self.config["DISABLE_PROMOTED_SERVICES"],
            landing_config_bunker_node=self.config["LANDING_CONFIG_BUNKER_NODE"],
            landing_config_bunker_node_version=(self.config["LANDING_CONFIG_BUNKER_NODE_VERSION"]),
        )

        _api = api.create(self.domain)

        return _api

    async def _setup_clients(self):
        clients = {
            "bvm_client": await BvmClient(self.config["BVM_URL"]),
            "geosearch_client": await GeoSearchClient(
                url=self.config["GEOSEARCH_URL"],
                tvm=self.tvm,
                tvm_destination=self.config["GEOSEARCH_TVM_ID"],
            ),
            "market_client": await MarketIntClient(url=self.config["MARKET_INT_URL"]),
            "avatars_client": await AvatarsClient(
                installation=self.config["AVATARS_INSTALLATION"],
                tvm_client=self.tvm,
                tvm_destination="avatars",
                namespace=self.config["AVATARS_STORE_NAMESPACE"],
            ),
            "ugcdb_client": await UgcdbClient(
                url=self.config["UGCDB_URL"],
                tvm=self.tvm,
                tvm_destination=self.config["UGCDB_TVM_ID"],
            ),
            "geobase_client": await GeoBaseClient(url=self.config["GEOBASE_URL"]),
            "bunker_client": await BunkerClient(url=self.config["BUNKER_URL"]),
            "tuner_client": await TunerClient(
                url=self.config["TUNER_URL"],
                tvm=self.tvm,
                tvm_destination="tuner",
                request_timeout=1,
            ),
        }
        for client in clients.values():
            self.register_client(client)

        yt_client = AsyncYtClient(
            yt_token=self.config["YT_TOKEN"],
            google_counters_table=self.config["YT_GOOGLE_COUNTERS_TABLE"],
        )
        yt_client.start()
        clients["yt_client"] = yt_client
        self._clients.append(client)

        ext_feed_writer = ExtFeedLogbrokerWriter(self.config)
        await ext_feed_writer.start()
        clients["ext_feed_writer"] = ext_feed_writer
        self._clients.append(ext_feed_writer)

        return clients
