# app/analytics/repository.py
from __future__ import annotations
from datetime import date
from typing import Dict, Iterable, List, Mapping, Optional, Sequence
# from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
# from  src.utils.db import get_session
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from .model import (
    AccountMetricsDaily, PostMetricsDaily, PostType,
    ConnectedAccount
    
)
from src.marketing.apps.Account.model import ConnectedAccount, MasterAccount

class AnalyticsRepository:
    def __init__(self, session: Session):
        self.session = session

    # ---------- read helpers ----------
    async def load_connected_account(self, connected_account_id: int) -> ConnectedAccount | None:
        stmt = (
            select(ConnectedAccount)
            .options(selectinload(ConnectedAccount.master_account_id))
            .where(ConnectedAccount.id == connected_account_id)
        )
        res = await self.session.execute(stmt)
        return res.scalar_one_or_none()

    async def map_external_posts_to_post_types(
        self, connected_account_id: int, external_ids: List[str]
    ) -> Dict[str, int]:
        if not external_ids:
            return {}
        stmt = select(PostType.id, PostType.link).where(
            PostType.connected_account_id == connected_account_id,
            PostType.link.in_(external_ids)
        )
        res = await self.session.execute(stmt)
        return {row.link: row.id for row in res.all()}

    # ---------- upserts (ORM) ----------
    async def upsert_account_metrics(
        self, connected_account_id: int, d: date, metrics: Dict[str, Optional[int | float]]
    ) -> None:
        entity = await self.session.get(
            AccountMetricsDaily,
            {"connected_account_id": connected_account_id, "metric_date": d}
        )
        if entity is None:
            entity = AccountMetricsDaily(
                connected_account_id=connected_account_id,
                metric_date=d
            )
            self.session.add(entity)

        for k, v in metrics.items():
            if hasattr(entity, k) and v is not None:
                setattr(entity, k, v)

    async def upsert_post_metrics_batch(
        self, connected_account_id: int, rows: List[Dict]
    ) -> int:
        """
        rows: [{"post_type_id": int, "metric_date": date, "metrics": {...}, "external_post_id": "...", "permalink": "..."}]
        """
        written = 0
        for r in rows:
            pk = {"post_type_id": r["post_type_id"], "metric_date": r["metric_date"]}
            entity = await self.session.get(PostMetricsDaily, pk)
            if entity is None:
                entity = PostMetricsDaily(**pk)
                self.session.add(entity)

            # set metrics
            m = r.get("metrics", {})
            for k, v in m.items():
                if hasattr(entity, k) and v is not None:
                    setattr(entity, k, int(v))

            if "external_post_id" in r:
                entity.external_post_id = r["external_post_id"]
            if "permalink" in r:
                entity.permalink = r["permalink"]
            written += 1
        return written
