# app/src/trading/accounts/service.py

from __future__ import annotations

from src.integrations.exchange.models import BalanceSummary
from src.integrations.exchange.service import ExchangeService
from src.integrations.exchange.status import (
    ExchangeStatusCode,
    build_exchange_error_status,
)
from src.storage.repositories.balance_snapshots import (
    BalanceSnapshotRepository,
)
from src.trading.journal.service import JournalService


class AccountsService:
    def __init__(self) -> None:
        self.exchange_service = ExchangeService()
        self.snapshot_repository = BalanceSnapshotRepository()
        self.journal = JournalService()

    # получить live balance summary через typed exchange runtime layer
    def get_live_balance_summary(self) -> list[BalanceSummary]:
        try:
            balances = self.exchange_service.get_balance_summary()

        except Exception as exc:
            runtime_status = build_exchange_error_status(exc)

            self._log_balance_runtime_error(runtime_status)

            raise

        self._save_snapshot(balances)

        return balances

    # сохранить snapshot баланса
    def _save_snapshot(
        self,
        balances: list[BalanceSummary],
    ) -> None:
        payload = {
            "assets": [
                {
                    "currency": item.currency,
                    "available": item.available,
                    "locked": item.locked,
                    "source": item.source,
                }
                for item in balances
            ]
        }

        try:
            self.snapshot_repository.add_snapshot(
                source="portfolio_screen",
                payload=payload,
            )

        except Exception as exc:
            try:
                self.journal.log_warning(
                    "balance_snapshot_error",
                    f"Не удалось сохранить snapshot баланса: {exc}",
                    {
                        "assets_count": len(balances),
                    },
                )

            except Exception:
                pass

            return

        try:
            self.journal.log_info(
                "balance_snapshot_saved",
                f"Snapshot баланса сохранён. Активов: {len(balances)}",
                {
                    "assets_count": len(balances),
                },
            )

        except Exception:
            pass

    # записать typed runtime exchange error для balances
    def _log_balance_runtime_error(
        self,
        runtime_status,
    ) -> None:
        try:
            payload = {
                "status_code": runtime_status.code.value,
                "is_available": runtime_status.is_available,
                "is_auth_ok": runtime_status.is_auth_ok,
                "reason": runtime_status.reason,
                "raw_status": runtime_status.raw_status,
                "raw_error": runtime_status.raw_error,
            }

            if runtime_status.code == ExchangeStatusCode.AUTH_ERROR:
                self.journal.log_warning(
                    "balance_auth_error",
                    runtime_status.message,
                    payload,
                )
                return

            self.journal.log_warning(
                "balance_exchange_error",
                runtime_status.message,
                payload,
            )

        except Exception:
            pass