"""
core/warmup_groups.py — поддержка нескольких own_chat подгрупп.

До этой фичи на ВСЕ N аккаунтов прогрева создавался один общий чат
(`warmup_own_chat_id`). При 21 акке = одинаковый набор участников
во всех «комьюнити», которые он создаёт → антифрод TG видит сеть.

Решение: бить акки на подгруппы по 3-7, создавать отдельный чат
для каждой. Хранение в user_settings:

  warmup_own_chats: [
      {chat_id, title, invite_link, members: [phone, ...]},
      ...
  ]

Legacy одиночный `warmup_own_chat_id` тоже поддерживается:
функции тут читают оба формата и нормализуют.
"""
from __future__ import annotations

import random
from typing import Dict, List, Optional, Tuple


def normalize_own_chats(user_settings: Dict) -> List[Dict]:
    """Возвращает список чатов в нормализованном формате.
    Если есть `warmup_own_chats` — возвращаем как есть.
    Если есть только legacy `warmup_own_chat_id` — заворачиваем в синтетический список.
    """
    chats = user_settings.get("warmup_own_chats") or []
    if isinstance(chats, list) and chats:
        return [c for c in chats if isinstance(c, dict) and c.get("chat_id")]
    legacy_id = int(user_settings.get("warmup_own_chat_id", 0) or 0)
    if legacy_id:
        return [{
            "chat_id": legacy_id,
            "title": user_settings.get("warmup_own_chat_title", ""),
            "invite_link": user_settings.get("warmup_own_chat_invite_link", ""),
            "members": [],  # legacy — не знаем точно, акки все
        }]
    return []


def get_own_chat_for_phone(user_settings: Dict, phone: str) -> Optional[Dict]:
    """Возвращает чат-объект (dict) для указанного аккаунта.
    Если у акка нет «своего» чата (нет в members) — возвращаем рандомный,
    чтобы он мог хотя бы share ссылку. В legacy-режиме (1 общий чат) — он же.
    """
    chats = normalize_own_chats(user_settings)
    if not chats:
        return None
    if not phone:
        return chats[0]
    phone_norm = str(phone).lstrip("+").strip()
    # 1) Точный match по members
    for c in chats:
        members = c.get("members") or []
        if any(str(m).lstrip("+").strip() == phone_norm for m in members):
            return c
    # 2) Если ни один чат не содержит phone (legacy или акк новый) — берём первый
    # (или random для слабого разбавления)
    return random.choice(chats)


def get_all_own_chat_ids(user_settings: Dict) -> List[int]:
    """Все chat_id известных own-чатов (для broadcast/детекции участия)."""
    chats = normalize_own_chats(user_settings)
    return [int(c["chat_id"]) for c in chats if c.get("chat_id")]


def split_into_subgroups(items: List, target_size: int = 5) -> List[List]:
    """Делит список на подгруппы по target_size элементов.
    Последняя группа может быть меньше но не меньше 2 (мерджим с предыдущей если меньше 2).

    Пример: 21 акк, target_size=5 → [5, 5, 5, 4, 2] → [5, 5, 5, 6] (последняя мерджится).
    """
    if target_size < 2:
        target_size = 2
    if not items:
        return []
    # Перемешиваем для разнообразия
    shuffled = list(items)
    random.shuffle(shuffled)
    groups: List[List] = []
    for i in range(0, len(shuffled), target_size):
        chunk = shuffled[i:i + target_size]
        groups.append(chunk)
    # Если последняя группа < 2 — мерджим с предыдущей
    if len(groups) >= 2 and len(groups[-1]) < 2:
        groups[-2].extend(groups.pop())
    return groups
