"""Destination channel registration and permission checks."""

from __future__ import annotations

import logging

from app.database.models import PublishChannel
from app.database.repositories import Repositories
from app.errors import ValidationError
from app.gateways.base import TelegramGateway

logger = logging.getLogger(__name__)


class ChannelService:
    def __init__(self, repos: Repositories, gateway: TelegramGateway) -> None:
        self.repos = repos
        self.gateway = gateway

    async def add(self, chat_id: int, actor_id: int) -> tuple[PublishChannel, bool]:
        try:
            chat = await self.gateway.get_chat(chat_id)
        except Exception as exc:
            raise ValidationError(
                "اطلاعات کانال خوانده نشد. ربات باید عضو کانال باشد و شناسه درست باشد."
            ) from exc
        if chat.chat_type not in {"channel", "group", "supergroup"}:
            raise ValidationError("فقط کانال یا گروه می‌تواند مقصد انتشار باشد.")
        can_post = False
        error = None
        try:
            me = await self.gateway.get_me()
            member = await self.gateway.get_chat_member(chat_id, me.id)
            can_post = member.status in {"creator", "administrator"}
            if not can_post:
                error = "ربات ادمین کانال نیست و ممکن است اجازه ارسال نداشته باشد."
        except Exception as exc:
            error = "بررسی دسترسی ربات ممکن نشد."
            logger.warning("channel access check failed: %s", type(exc).__name__)
        channel, created = await self.repos.channels.add(
            chat_id,
            title=chat.title,
            username=chat.username,
            chat_type=chat.chat_type,
            added_by=actor_id,
            can_post=can_post,
            error=error,
        )
        await self.repos.audit.log(
            actor_id,
            "channel.add",
            entity_type="publish_channel",
            entity_id=chat_id,
            details={"created": created, "can_post": can_post},
        )
        return channel, created

    async def check(self, channel_id: int) -> bool:
        channel = await self.repos.channels.get(channel_id)
        if channel is None:
            return False
        try:
            chat = await self.gateway.get_chat(channel.chat_id)
            me = await self.gateway.get_me()
            member = await self.gateway.get_chat_member(channel.chat_id, me.id)
            can_post = member.status in {"creator", "administrator"}
            await self.repos.channels.update_access(
                channel_id,
                can_post=can_post,
                error=None if can_post else "ربات ادمین کانال نیست.",
                title=chat.title,
                username=chat.username,
            )
            return can_post
        except Exception as exc:
            logger.warning("channel check failed for %s: %s", channel.chat_id, type(exc).__name__)
            await self.repos.channels.update_access(
                channel_id,
                can_post=False,
                error="بررسی دسترسی ربات ممکن نشد.",
            )
            return False

    async def refresh_all(self) -> dict[int, bool]:
        result: dict[int, bool] = {}
        for channel in await self.repos.channels.list(active_only=True):
            result[channel.id] = await self.check(channel.id)
        return result
