"""
Enterprise Add Account Handler
Compatible with MultiSessionRunner
Race-safe + Dynamic Cooldown
"""

import asyncio
import time
import random

from ...client.create_client import SessionCreator
from ...core.logger import get_action_logger
from ...runner.multi_session_runner import runner  # ← مهم


class AddAccountHandler:

    def __init__(self):
        self.creator = SessionCreator()
        self.states = {}

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

        user_id = message.from_user.id
        text = (message.text or "").strip()

        if not text:
            return

        text_lower = text.lower()

        # ==================================================
        # START COMMAND
        # ==================================================
        if text_lower in ["/addaccount", "addaccount"]:

            self.states[user_id] = {
                "step": "phone",
                "unlock_time": 0,
            }

            return await message.reply_text(
                "📱 Send phone number with country code\n"
                "Example:\n+491234567890\n\n"
                "Type /cancel to abort."
            )

        # ==================================================
        # CANCEL
        # ==================================================
        if text_lower in ["cancel", "/cancel"]:

            state = self.states.get(user_id)

            if not state:
                return await message.reply_text("No active process.")

            phone = state.get("phone")

            if phone and phone in self.creator.pending:
                try:
                    app = self.creator.pending[phone]["app"]
                    await app.disconnect()
                except Exception:
                    pass

                self.creator.pending.pop(phone, None)

            self.states.pop(user_id, None)

            return await message.reply_text("❌ Add account cancelled")

        # ==================================================
        # NO ACTIVE PROCESS
        # ==================================================
        if user_id not in self.states:
            return

        state = self.states[user_id]
        now = time.time()

        # ==================================================
        # COOLDOWN CHECK
        # ==================================================
        if now < state.get("unlock_time", 0):
            remaining = int(state["unlock_time"] - now)
            return await message.reply_text(
                f"⏳ Please wait {remaining}s..."
            )

        # ==================================================
        # STEP 1 → PHONE
        # ==================================================
        if state["step"] == "phone":

            phone = text
            logger = get_action_logger(
                action="add_account",
                session=phone
            )

            cooldown = random.randint(6, 14)

            await runner.acquire_pool_lock()
            try:
                await self.creator.send_code(phone)
            except Exception as e:
                logger.exception(f"Send code failed → {e}")
                return await message.reply_text("Failed to send code")
            finally:
                runner.release_pool_lock()

            state.update({
                "step": "code",
                "phone": phone,
                "unlock_time": time.time() + cooldown
            })

            await self._countdown(
                message,
                f"📩 Code sent to {phone}\nWait",
                cooldown
            )

            return await message.reply_text("✅ Now send the code")

        # ==================================================
        # STEP 2 → CODE
        # ==================================================
        if state["step"] == "code":

            phone = state["phone"]
            code = text

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

            cooldown = random.randint(6, 14)

            await self._countdown(
                message,
                "⏳ Processing login in",
                cooldown
            )

            await runner.acquire_pool_lock()
            try:
                result = await self.creator.login_with_code(
                    phone,
                    code
                )
            except Exception as e:
                logger.exception(f"Login error → {e}")
                return await message.reply_text("Login failed")
            finally:
                runner.release_pool_lock()

            if result is True:
                logger.info("Login success")

                # بعد از لاگین، watcher خودش sync می‌کند
                self.states.pop(user_id, None)

                return await message.reply_text(
                    "Account added successfully ✅"
                )

            if result == "2FA":

                state.update({
                    "step": "password",
                    "unlock_time": time.time() + cooldown
                })

                return await message.reply_text(
                    "🔐 2FA enabled\nNow send your password"
                )

            logger.warning("Invalid code")
            return await message.reply_text(
                "Invalid or expired code"
            )

        # ==================================================
        # STEP 3 → PASSWORD
        # ==================================================
        if state["step"] == "password":

            phone = state["phone"]
            password = text

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

            cooldown = random.randint(6, 14)

            await self._countdown(
                message,
                "⏳ Verifying password in",
                cooldown
            )

            await runner.acquire_pool_lock()
            try:
                success = await self.creator.login_with_password(
                    phone,
                    password
                )
            except Exception as e:
                logger.exception(f"2FA error → {e}")
                return await message.reply_text(
                    "Password verification failed"
                )
            finally:
                runner.release_pool_lock()

            if success:
                logger.info("Login success with 2FA")

                self.states.pop(user_id, None)

                return await message.reply_text(
                    "Account added successfully ✅"
                )

            logger.warning("Wrong password")
            return await message.reply_text("Wrong password")

    # ==================================================
    # LIVE COUNTDOWN
    # ==================================================
    async def _countdown(self, message, base_text, seconds):

        countdown_msg = await message.reply_text(
            f"{base_text} {seconds}s"
        )

        for remaining in range(seconds - 1, -1, -1):
            await asyncio.sleep(1)
            try:
                await countdown_msg.edit_text(
                    f"{base_text} {remaining}s"
                )
            except Exception:
                pass