from ObjectiveC.oc_custom import custom_image
from ObjectiveC.oc_custom import custom_pbxproj
from ObjectiveC import oc_util
from ObjectiveC.oc_custom.custom_file import delete_debug_macros
from ObjectiveC.oc_custom.custom_md_to_html import md_to_html
from ObjectiveC.oc_custom import custom_util
from ObjectiveC.oc_custom import custom_replace
import os
import re
from ObjectiveC.oc_custom import custom_project

# 国内还是国外 1国内 2海外


def init(sdk_cn_or_os):
    print('j资源加密处理开始...')
    custom_image.init()
    print('j资源加密处理完成')

    print('j删除所有 XXGPLAYKIT_DEBUG 宏定义块')
    delete_debug_macros()
    print('j删除所有 XXGPLAYKIT_DEBUG 宏定义块完成')

    print('j清空 Target 的预处理器定义 (GCC_PREPROCESSOR_DEFINITIONS)')
    proj_path = f'{oc_util.path_mix_project}/{oc_util.name_current_project}.xcodeproj/project.pbxproj'
    custom_pbxproj.clear_target_preprocessor_definitions(
        proj_path, oc_util.name_current_project)
    print('j清空 Target 的预处理器定义 (GCC_PREPROCESSOR_DEFINITIONS)完成')

    print('j处理SDK对接文档开始...')
    # 根据用户选择的SDK来动态生成需要保留的篇章
    needed_sdks = get_needed_sdks_from_options(
        sdk_cn_or_os, custom_util.sdk_options)
    handle_sdk_doc(sdk_cn_or_os, needed_sdks)
    print('j处理SDK对接文档完成')

    print('j修改XXGThirdMiddlewares名字')
    new_thirdmiddlewares_name = custom_project.custom_modify_project_name(
        oc_util.path_mix_project, 'XXGThirdMiddlewares')
    print('j修改XXGThirdMiddlewares名字完成')

    # 处理podfile文件 {oc_util.path_mix_project}/XXGPlayKitOSDemo/podfile
    if custom_util.need_pods == True:
        print('j处理podfile文件')
        handle_podfile(new_thirdmiddlewares_name)

    # 从混淆后的 XXGThirdMiddlewares 工程中提取需要导出的 .a 文件名
    print('j提取需要导出的 .a 文件名白名单')
    extract_exported_lib_names(new_thirdmiddlewares_name)

    # 处理脚本
    handle_script()


def handle_podfile(new_thirdmiddlewares_name):
    """
    处理podfile文件，将XXGAppLovinMiddleware相关内容替换为新的名称

    Args:
        new_thirdmiddlewares_name: 新的ThirdMiddlewares项目名称
    """
    # 兼容大小写:macOS APFS 默认大小写不敏感,但 Linux ext4 敏感。
    # 源工程实际文件名是小写 podfile,大写 Podfile 也是 CocoaPods 官方推荐写法,这里两种都尝试。
    podfile_dir = f'{oc_util.path_mix_project}/XXGPlayKitOSDemo'
    podfile_path = None
    for candidate_name in ('Podfile', 'podfile'):
        candidate_path = f'{podfile_dir}/{candidate_name}'
        if os.path.exists(candidate_path):
            podfile_path = candidate_path
            break

    if podfile_path is None:
        print(f'Podfile文件不存在(已尝试 Podfile 和 podfile): {podfile_dir}')
        return

    # 从文件名混淆日志中查找XXGAppLovinMiddleware的新名字
    new_applovin_name = get_obfuscated_name_from_log('XXGAppLovinMiddleware')
    if not new_applovin_name:
        print('未找到XXGAppLovinMiddleware的混淆名称，跳过Podfile处理')
        return

    try:
        # 读取Podfile内容
        with open(podfile_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 定义替换模式
        pattern_replacements = [
            # 替换target名称为混淆后的名称
            (r"target 'XXGAppLovinMiddleware'",
             f"target '{new_applovin_name}'"),
            # 替换project路径中的项目名
            (r"project '\.\./XXGThirdMiddlewares/XXGThirdMiddlewares\.xcodeproj'",
             f"project '../XXGThirdMiddlewares/{new_thirdmiddlewares_name}.xcodeproj'")
        ]

        # 执行替换
        original_content = content
        content = custom_replace.replace_multiple_patterns_in_content(
            content, pattern_replacements)

        # 检查是否有变化
        if content != original_content:
            # 写回文件
            with open(podfile_path, 'w', encoding='utf-8') as file:
                file.write(content)
            print(f'已更新Podfile文件: {podfile_path}')
            print(f'XXGAppLovinMiddleware -> {new_applovin_name}')
            print(
                f'XXGThirdMiddlewares.xcodeproj -> {new_thirdmiddlewares_name}.xcodeproj')
        else:
            print('Podfile文件中未找到需要替换的内容')

    except Exception as e:
        print(f'处理Podfile文件时出错: {e}')


def extract_exported_lib_names(new_thirdmiddlewares_name):
    """
    解析混淆改名后的 XXGThirdMiddlewares.xcodeproj，
    根据 custom_util.exported_lib_names 中登记的原始 Middleware target 名，
    提取对应的混淆后 productName，组装成 lib<混淆名>.a 列表，
    覆盖写回 custom_util.exported_lib_names，供 handle_script 注入 build.sh。

    策略:
    - 改名后原 target 名 'XXGAppLovinMiddleware' 已不存在，
      但每个 Middleware target 都有一个与原名同名的 .m 源文件,
      通过文件名混淆日志反查新名即可得到混淆后的 target/product 名。
    - 若日志缺失，再兜底尝试读取 pbxproj 的 productReference.path。
    """
    original_names = list(custom_util.exported_lib_names or [])
    if not original_names:
        print('没有保留的 Middleware，跳过 .a 白名单提取')
        custom_util.exported_lib_names = []
        return

    lib_names = []
    # 优先走文件名混淆日志（已验证的、现有可行路径）
    for original in original_names:
        new_name = get_obfuscated_name_from_log(original)
        if new_name:
            lib_names.append(f'lib{new_name}.a')
        else:
            # 兜底：尝试从 pbxproj 读取（如果某些 target 未出现在 .m 混淆日志里）
            fallback = _get_product_name_from_pbxproj(
                new_thirdmiddlewares_name, original)
            if fallback:
                lib_names.append(f'lib{fallback}.a')
            else:
                print(f'警告: 无法找到 {original} 的混淆后名字，白名单将缺失')

    custom_util.exported_lib_names = lib_names
    print(f'需要导出的 .a 白名单: {lib_names}')


def _get_product_name_from_pbxproj(new_thirdmiddlewares_name, original_target_name):
    """
    兜底：从改名后的 XXGThirdMiddlewares pbxproj 中，
    按 productName 的 basename 反查 target 对应的混淆后产品名。
    因为 target 名此时已经是混淆后的随机名，无法直接按 original_target_name 查，
    这里只能做尽量多的匹配（保留给将来扩展），失败返回 None。
    """
    try:
        from pbxproj import XcodeProject
        pbx_path = f'{oc_util.path_mix_project}/XXGThirdMiddlewares/{new_thirdmiddlewares_name}.xcodeproj/project.pbxproj'
        if not os.path.exists(pbx_path):
            return None
        project = XcodeProject.load(pbx_path)
        # 暂无可靠的原名反查手段，预留接口
        return None
    except Exception as e:
        print(f'读取 pbxproj 失败: {e}')
        return None


def get_obfuscated_name_from_log(original_name):

    """
    从文件名混淆日志中查找原始名称对应的混淆后名称

    Args:
        original_name: 原始名称，如 'XXGAppLovinMiddleware'

    Returns:
        混淆后的名称，如果未找到则返回None
    """
    log_file_path = f'{oc_util.path_mix}/文件名混淆日志.txt'

    if not os.path.exists(log_file_path):
        print(f'文件名混淆日志不存在: {log_file_path}')
        return None

    try:
        with open(log_file_path, 'r', encoding='utf-8') as file:
            for line in file:
                line = line.strip()
                # 查找格式：原文件名:XXGAppLovinMiddleware.m                  被修改为:CreditDecideTeamColorAssertArt.m
                if f'原文件名:{original_name}.m' in line and '被修改为:' in line:
                    # 提取新名称
                    parts = line.split('被修改为:')
                    if len(parts) >= 2:
                        new_filename = parts[1].strip()
                        # 去掉.m扩展名
                        if new_filename.endswith('.m'):
                            new_name = new_filename[:-2]
                            print(f'从混淆日志中找到: {original_name} -> {new_name}')
                            return new_name

        print(f'在混淆日志中未找到 {original_name} 的记录')
        return None

    except Exception as e:
        print(f'读取文件名混淆日志时出错: {e}')
        return None


def get_needed_sdks_from_options(sdk_cn_or_os, sdk_options):
    """
    根据用户选择的SDK选项生成需要保留的文档篇章列表

    Args:
        sdk_cn_or_os: '1' 表示国内版，其他表示海外版
        sdk_options: 用户选择的SDK选项字符串，用逗号分隔

    Returns:
        需要保留的篇章名称列表
    """
    # 始终保留基础篇
    needed_sdks = ['基础']

    if not sdk_options:
        print('未指定SDK选项，只保留基础篇')
        return needed_sdks

    # 建立SDK选项到文档篇章的映射关系
    if sdk_cn_or_os == '1':  # 国内版
        sdk_mapping = {
            'ShanYanSDK(一键登录)': '',  # 闪验SDK没有单独篇章，集成在基础篇中
            'ShanYanSDK': '',  # 简化版本
            'BDASignalManager(巨量归因)': '巨量',
            'BDASignalManager': '巨量',  # 简化版本
            'CSJ': 'CSJ',
            'CSJ(激励广告)': '穿山甲',
            'ShareSDK(分享)': 'ShareSDK',
            'ShareSDK': 'ShareSDK'  # 简化版本
        }
    else:  # 海外版
        sdk_mapping = {
            'AppsFlyer': 'AppsFlyer',
            'Facebook': 'Facebook',
            'Firebase': 'Firebase',
            'Adjust': 'Adjust',
            'VK(俄罗斯VK登录)': 'VK',
            'VK': 'VK',  # 简化版本
            'AppLovin(Max广告)': 'AppLovin',
            'AppLovin': 'AppLovin',  # 简化版本
            'Poopo(渠道)': 'Poopo',  # Poopo渠道使用单独的Poopo篇章
            'ADP': 'ADP',
            'ADP(IAA项目)': 'ADP'
        }

    # 解析用户选择的SDK选项
    selected_sdks = [sdk.strip() for sdk in sdk_options.split(',')]

    for sdk in selected_sdks:
        if sdk in sdk_mapping and sdk_mapping[sdk]:
            chapter_name = sdk_mapping[sdk]
            if chapter_name not in needed_sdks:
                needed_sdks.append(chapter_name)
                print(f'添加篇章: {chapter_name} (对应SDK: {sdk})')
        elif sdk in sdk_mapping and not sdk_mapping[sdk]:
            print(f'SDK {sdk} 集成在基础篇中，无需额外篇章')
        else:
            print(f'警告: 未找到SDK {sdk} 对应的文档篇章')

    print(f'最终保留的篇章: {", ".join(needed_sdks)}')
    return needed_sdks

# 处理SDK对接文档


def handle_sdk_doc(sdk_cn_or_os, needed_sdks=None):
    """
    处理SDK对接文档

    Args:
        sdk_cn_or_os: '1' 表示国内版，其他表示海外版
        needed_sdks: 需要保留的SDK篇章列表，例如 ['基础', 'Facebook', 'Firebase']
                    如果为None，则保留所有篇章
    """
    # 文档路径
    doc_dir = f'{oc_util.path_mix_project}/SDK对接文档/'
    cn_doc = f'{doc_dir}闲闲SDK-国内版-iOS接入文档（3.0）.md'
    os_doc = f'{doc_dir}闲闲SDK-海外版-iOS接入文档（3.0）.md'

    # 根据参数保留对应文档并删除另一个
    if sdk_cn_or_os == '1':  # 国内版
        keep_doc = cn_doc
        delete_doc = os_doc
    else:  # 海外版
        keep_doc = os_doc
        delete_doc = cn_doc

    # 删除不需要的文档
    if os.path.exists(delete_doc):
        os.remove(delete_doc)
        print(f'已删除文档: {delete_doc}')

    # 如果需要过滤SDK篇章且保留的文档存在
    if needed_sdks and os.path.exists(keep_doc):
        filtered_content = filter_sdk_chapters(keep_doc, needed_sdks)
        if filtered_content:
            # 写回过滤后的内容
            with open(keep_doc, 'w', encoding='utf-8') as file:
                file.write(filtered_content)
            print(f'已过滤文档篇章，保留的SDK: {", ".join(needed_sdks)}')

    # 将保留的文档转换为HTML
    if os.path.exists(keep_doc):
        html_file = md_to_html(keep_doc)
        # if html_file:
        #     pdf_file = html_to_pdf(html_file)
        #     if pdf_file:
        #         print(f'已将文档转换为PDF: {pdf_file}')
        # 删除原始的Markdown文件
        os.remove(keep_doc)
        print(f'已删除原始Markdown文档: {keep_doc}')


def filter_sdk_chapters(doc_path, needed_sdks):
    """
    根据需要的SDK列表过滤文档篇章

    Args:
        doc_path: 文档路径
        needed_sdks: 需要保留的SDK列表，例如 ['基础', 'Facebook', 'Firebase']

    Returns:
        过滤后的文档内容
    """
    try:
        with open(doc_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 使用正则表达式分割文档篇章
        # 篇章分隔符格式：=== [篇章名] ===
        chapters = re.split(r'=== \[([^\]]+)\] ===', content)

        # chapters[0] 是第一个分隔符之前的内容（文档头部）
        # chapters[1], chapters[3], chapters[5]... 是篇章名
        # chapters[2], chapters[4], chapters[6]... 是篇章内容

        if len(chapters) < 3:
            # 如果没有找到篇章分隔符，返回原内容
            print('文档中未找到篇章分隔符，保留原始内容')
            return content

        # 构建新的文档内容
        filtered_content = chapters[0]  # 保留文档头部

        # 遍历篇章
        for i in range(1, len(chapters), 2):
            if i + 1 < len(chapters):
                chapter_name = chapters[i].strip()
                chapter_content = chapters[i + 1]

                # 检查是否需要保留这个篇章
                should_keep = False
                for needed_sdk in needed_sdks:
                    if needed_sdk.lower() in chapter_name.lower():
                        should_keep = True
                        break

                if should_keep:
                    filtered_content += chapter_content
                    print(f'保留篇章: {chapter_name}')
                else:
                    print(f'移除篇章: {chapter_name}')

        return filtered_content

    except Exception as e:
        print(f'过滤文档篇章时出错: {e}')
        return None

# 处理脚本


def handle_script():
    sdk_cn_or_os = custom_util.sdk_cn_or_os
    script_path = f'{oc_util.path_mix_project}/scripts/build.sh'

    # 根据版本确定项目名称和版本信息
    if sdk_cn_or_os == '1':  # 国内版
        project_name = 'XXGPlayKitCNDemo'
        cn_or_os_text = '国内版'
    else:  # 海外版
        # 如果是pods版本，则使用 XXGPlayKitOSDemo-Pods 作为项目名称
        if custom_util.need_pods == True:
            project_name = 'XXGPlayKitOSDemo-Pods'
        else:
            project_name = 'XXGPlayKitOSDemo'
        cn_or_os_text = '国际版'

    # SDK信息
    sdk_name = oc_util.name_current_project
    sdk_version = custom_util.sdk_version

    # 读取脚本文件内容
    try:
        with open(script_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 组装 .a 白名单为 shell 数组字符串，例如:
        # EXPORTED_LIBS=("libAbc.a" "libXyz.a")
        lib_names = list(custom_util.exported_lib_names or [])
        if lib_names:
            libs_str = ' '.join(f'"{name}"' for name in lib_names)
            exported_libs_line = f'EXPORTED_LIBS=({libs_str})'
        else:
            exported_libs_line = 'EXPORTED_LIBS=()'

        # 定义所有需要替换的模式
        pattern_replacements = [
            # 工作区路径
            # (r'WORKSPACE_PATH="[^"]*"', f'WORKSPACE_PATH="../{sdk_name}.xcworkspace"'),
            # SDK名称
            (r'SDK_NAME="[^"]*"', f'SDK_NAME="{sdk_name}"'),
            # SDK版本
            (r'SDK_VERSION="[^"]*"', f'SDK_VERSION="v{sdk_version}"'),
            # 版本类型
            (r'CN_OR_OS="[^"]*"', f'CN_OR_OS="{cn_or_os_text}"'),
            # Scheme名称
            (r'SCHEME_NAME="[^"]*"', f'SCHEME_NAME="{project_name}"'),
            # 导出 .a 白名单（由 handle_script 动态注入）
            (r'EXPORTED_LIBS=\([^)]*\)', exported_libs_line),
        ]


        # 批量替换所有模式
        content = custom_replace.replace_multiple_patterns_in_content(
            content, pattern_replacements)

        # 写回文件
        with open(script_path, 'w', encoding='utf-8') as file:
            file.write(content)

        print(f'已更新脚本文件: {script_path}')
        # print(f'WORKSPACE_PATH="../{sdk_name}.xcworkspace"')
        print(f'SDK_NAME="{sdk_name}"')
        print(f'SDK_VERSION="v{sdk_version}"')
        print(f'CN_OR_OS="{cn_or_os_text}"')
        print(f'SCHEME_NAME="{project_name}"')

    except Exception as e:
        print(f'处理脚本文件时出错: {e}')
