import os
import time
import asyncio

from loguru import logger
from opentele.api import API
from telethon import TelegramClient
from telethon.errors import SessionPasswordNeededError, PhoneCodeInvalidError, RPCError, PhoneNumberBannedError

from tootls import split_phone_number, get_code
from models.tg_phone_devices import TgPhoneDevices


async def get_device_info():
    """
    获取设备信息
    """


    NewApi = API.TelegramDesktop.Generate(system="windows")
    return {
        "api_id": NewApi.api_id,
        "api_hash": NewApi.api_hash,
        "device_model": NewApi.device_model,
        "system_version": NewApi.system_version,
        "app_version": NewApi.app_version,
        "lang_code": NewApi.lang_code,
        "system_lang_code": NewApi.system_lang_code
    }


async def create_telegram_client(server):
    """
    创建并配置 Telegram 客户端
    """
    PROXY_CONFIG = {
        'proxy_type': 'http',  # 或 'socks4'，具体看你的代理类型
        'addr': '192.168.50.220',  # 代理服务器地址
        'port': 10809,  # 代理服务器端口
        'username': '',  # 如果有用户名，填写
        'password': ''  # 如果有密码，填写
    }

    client = TelegramClient(
        fr"C:\sessions\{server.phone}",
        api_id=server.api_id,
        api_hash=server.api_hash,
        device_model=server.device_model,
        system_version=server.system_version,
        app_version=server.app_version,
        system_lang_code=server.system_lang_code,
        lang_code=server.lang_code,
        proxy=PROXY_CONFIG
    )
    return client


async def login_telegram(client, url, server):
    """
    处理登录流程
    """
    try:
        sent_code_info = await client.send_code_request(server.phone)
        time.sleep(5)
        code1, code2 = get_code(url=url)

        logger.info(f"账号：{server.phone}，发送验证码成功》》》")

        try:
            await client.sign_in(phone=server.phone, code=code1)
            logger.info(f"账号：{server.phone}，输入验证码成功》》》")

        except PhoneCodeInvalidError:
            logger.error(f"账号 {server.phone}，验证码无效，请重试")
            return 3
        except SessionPasswordNeededError:
            password = code2
            if server.to_code:
                password = server.to_code
            await client.sign_in(password=password)

            logger.info(f"账号：{server.phone}，输入2fa成功》》》")

            server.code = password
            server.save()

        return 1
    except PhoneNumberBannedError:
        logger.error(f"账号 {server.phone}，已被封禁!!!")
        return 4

    except (RPCError, Exception) as e:
        logger.error(f'账号：{server.phone}，登录失败，错误信息：{e}')
        return 0


async def handle_login_failure(url, server):
    """
    处理登录失败的情况
    """

    time.sleep(5)

    session_file = fr"C:\sessions\{server.phone}.session"
    if os.path.exists(session_file):
        os.remove(session_file)
        print(f"文件 {session_file} 已删除")

    # 更新服务器信息
    server.area_code = server.area_code
    server.api_id = server.api_id
    server.api_hash = server.api_hash
    server.device_model = server.device_model
    server.system_version = server.system_version
    server.app_version = server.app_version
    server.system_lang_code = server.system_lang_code
    server.lang_code = server.lang_code
    server.phone = server.phone
    server.save()

    # 重新创建客户端并尝试登录
    client = await create_telegram_client(server)
    login_start = await login_telegram(client, url, server)

    if login_start == 1:
        me = await client.get_me()
        logger.info(f'账号 {server.phone} -- {me.first_name} 登录成功！')
        server.is_valid_session = "1"
        server.save()
    elif login_start == 0:
        logger.error("Telegram 登录失败")
        server.is_valid_session = "0"
        server.save()


async def main(_, country_code, local_number, url, semaphore):
    async with semaphore:

        device_info = await get_device_info()
        area_code = country_code
        phone_number = local_number

        server, created = TgPhoneDevices().get_or_create(
            phone=area_code + phone_number,
        )

        if server.is_valid_session:
            logger.info(f"第{_}，账号 {server.phone}，登录成功！！！")
            return

        if server.is_valid_session is None:
            server.area_code = area_code
            server.phone_number = phone_number
            server.api_id = device_info["api_id"]
            server.api_hash = device_info["api_hash"]
            server.device_model = device_info["device_model"]
            server.system_version = device_info["system_version"]
            server.app_version = device_info["app_version"]
            server.system_lang_code = device_info["system_lang_code"]
            server.lang_code = device_info["lang_code"]
            server.phone = area_code + phone_number
            server.save()

        logger.info(f"第{_}，账号：{server.phone}，开始登录。。。")

        try:
            client = await create_telegram_client(server)
            await client.connect()

            if await client.is_user_authorized():
                me = await client.get_me()
                logger.info(f'第{_}，账号：{server.phone} -- {me.first_name} 登录成功！')
                await client.disconnect()
                return

            login_start = await login_telegram(client, url, server)

            if login_start == 1:
                me = await client.get_me()
                logger.info(f'第{_}，账号 {server.phone} -- {me.first_name} 登录成功！')
                server.is_valid_session = "1"
                server.save()
            elif login_start == 0:
                logger.error(f"第{_}，账号 {server.phone}，Telegram 登录失败")
                server.is_valid_session = "0"
                server.save()
            elif login_start == 3:
                await client.disconnect()

                await handle_login_failure(url, server)
            elif login_start == 4:
                server.is_valid_session = -1
                server.save()

            await client.disconnect()
        except:
            pass


async def main1():
    # 定义最大并发任务数
    max_concurrent_tasks = 3
    # 创建一个信号量对象
    semaphore = asyncio.Semaphore(max_concurrent_tasks)

    with open('电话号码文件夹/200tg(3).txt', 'r', encoding='utf-8') as f:
        content = f.read()

    tasks = []  # 创建任务列表
    lines = content.split('\n')
    for _, line in enumerate(lines):
        if '|' in line:
            phone, url = line.split('|')
            country_code, local_number = split_phone_number(phone_number=phone)
            if country_code and local_number:
                tasks.append(main(_, country_code, local_number, url, semaphore))

    # 并发运行所有任务
    await asyncio.gather(*tasks)


if __name__ == '__main__':
    # with open('86卡密导出(200)-2025-02-28 15_30_20(1).txt', 'r', encoding='utf-8') as f:
    #     content = f.read()
    #
    # lines = content.split('\n')
    # for _, line in enumerate(lines):
    #     if '----' in line:
    #         phone, url = line.split('----')
    #         country_code, local_number = split_phone_number(phone_number=phone)
    #         if country_code and local_number:
    #             asyncio.run(main(_, country_code, local_number, url))

    asyncio.run(main1())
