# scraper2_hj3415/app/dart/composition.py
from __future__ import annotations

from dataclasses import dataclass

from db2_hj3415.common.types import MongoDoc
from pymongo.asynchronous.database import AsyncDatabase
from scraper2_hj3415.app.dart.adapters.out.dart_http_client import (
    DartHttpClient,
)
from scraper2_hj3415.app.dart.adapters.out.krx300_provider import (
    Krx300Provider,
)
from scraper2_hj3415.app.dart.ports.dart.dart_client_port import DartClientPort
from scraper2_hj3415.app.dart.ports.universe.stock_universe_port import (
    StockUniversePort,
)
from scraper2_hj3415.app.dart.usecases.collect_dart_reports import (
    CollectDartReportsUsecase,
)


@dataclass(frozen=True)
class DartResources:
    """
    dart 기능 내부 리소스 묶음.

    - dart_client: OpenDART API 호출 어댑터
    - stock_universe: 종목 유니버스 제공 어댑터
    """

    dart_client: DartClientPort
    stock_universe: StockUniversePort


@dataclass(frozen=True)
class DartUsecases:
    """
    dart 기능 유스케이스 묶음.
    """

    collect_reports: CollectDartReportsUsecase
    resources: DartResources


def build_dart_resources(
    *,
    dart_api_key: str,
    db: AsyncDatabase[MongoDoc],
) -> DartResources:
    """
    dart 기능이 사용하는 외부 어댑터를 조립한다.

    책임:
    - OpenDART HTTP client 생성
    - KRX300 유니버스 provider 생성
    """
    dart_client: DartClientPort = DartHttpClient(api_key=dart_api_key)
    stock_universe: StockUniversePort = Krx300Provider(db=db)

    return DartResources(
        dart_client=dart_client,
        stock_universe=stock_universe,
    )


def build_dart_usecases(
    *,
    dart_api_key: str,
    db: AsyncDatabase[MongoDoc],
) -> DartUsecases:
    """
    dart 기능 전용 composition helper.

    주의:
    - 환경변수는 여기서 읽지 않는다.
    - 필요한 설정값은 상위 composition root에서 주입한다.
    """
    resources = build_dart_resources(
        dart_api_key=dart_api_key,
        db=db,
    )

    return DartUsecases(
        collect_reports=CollectDartReportsUsecase(
            dart_client=resources.dart_client,
            stock_universe_port=resources.stock_universe,
        ),
        resources=resources,
    )
