"""
Join / Leave handler
Universal link + username + id

Enhanced:
- Auto mute after join
- Micro delay (1–3 sec)
- Delay engine integrated
- Flood isolation
- Logger integrated
"""

import asyncio
import random

from pyrogram.errors import FloodWait, RPCError

from remottxrea.actions.join_leave import (
    JoinLeaveManager
)

from remottxrea.actions.auto_mute import (
    AutoMuteManager
)

from remottxrea.core.logger import (
    get_action_logger
)

from remottxrea.core.delay_engine import (
    delay_engine
)


class JoinLeaveHandler:

    def __init__(self, runner):
        self.runner = runner

    # =============================================
    async def handle(self, message):

        text = message.text.strip()

        # =============================================
        # JOIN + AUTO MUTE
        # =============================================
        if text.startswith("join"):

            try:
                link = text.split(" ", 1)[1]
            except IndexError:
                return await message.reply_text(
                    "Usage:\njoin <link>"
                )

            # -----------------------------------------
            async def action(phone, app):

                logger = get_action_logger(
                    action="join_leave",
                    session=phone
                )

                joiner = JoinLeaveManager(app, phone)
                muter = AutoMuteManager(app, phone)

                try:

                    # ---------- JOIN ----------
                    joined = await joiner.join(link)

                    if not joined:
                        logger.warning(
                            f"Join failed → {link}"
                        )
                        return False

                    logger.info(
                        f"Joined → {link}"
                    )

                    # ---------- DELAY ENGINE ----------
                    await delay_engine.join_delay()

                    # ---------- MICRO DELAY ----------
                    delay = random.uniform(1, 3)

                    logger.info(
                        f"Pre-mute micro delay → {delay:.2f}s"
                    )

                    await asyncio.sleep(delay)

                    # ---------- MUTE ----------
                    muted = await muter.mute(
                        link,
                        hours=None
                    )

                    if muted:
                        logger.info(
                            f"Muted → {link}"
                        )
                        return True
                    else:
                        logger.warning(
                            f"Mute failed → {link}"
                        )
                        return False

                # ---------- FLOOD ----------
                except FloodWait as e:

                    logger.warning(
                        f"FloodWait {e.value}s"
                    )

                    await asyncio.sleep(e.value)
                    return False

                # ---------- RPC ----------
                except RPCError as e:

                    logger.error(
                        f"RPC Error → {e}"
                    )
                    return False

                # ---------- GENERIC ----------
                except Exception as e:

                    logger.exception(
                        f"Join/Mute error → {e}"
                    )
                    return False

            # -----------------------------------------
            results = await self.runner.run_action(
                action
            )

            success = sum(
                1 for r in results if r
            )
            failed = len(results) - success

            return await message.reply_text(
                "Join + Mute Completed\n\n"
                f"Success: {success}\n"
                f"Failed: {failed}"
            )

        # =============================================
        # LEAVE
        # =============================================
        if text.startswith("leave"):

            try:
                target = text.split(" ", 1)[1]
            except IndexError:
                return await message.reply_text(
                    "Usage:\nleave <target>"
                )

            # -----------------------------------------
            async def action(phone, app):

                logger = get_action_logger(
                    action="join_leave",
                    session=phone
                )

                manager = JoinLeaveManager(
                    app,
                    phone
                )

                try:

                    left = await manager.leave(
                        target
                    )

                    if left:
                        logger.info(
                            f"Left → {target}"
                        )
                        return True
                    else:
                        logger.warning(
                            f"Leave failed → {target}"
                        )
                        return False

                except FloodWait as e:

                    logger.warning(
                        f"FloodWait {e.value}s"
                    )

                    await asyncio.sleep(e.value)
                    return False

                except RPCError as e:

                    logger.error(
                        f"RPC Error → {e}"
                    )
                    return False

                except Exception as e:

                    logger.exception(
                        f"Leave error → {e}"
                    )
                    return False

            # -----------------------------------------
            results = await self.runner.run_action(
                action
            )

            success = sum(
                1 for r in results if r
            )
            failed = len(results) - success

            return await message.reply_text(
                "Leave Completed\n\n"
                f"Success: {success}\n"
                f"Failed: {failed}"
            )
