# pylint:disable=E0401
import hashlib
import json
import logging
import os
import re
import requests
from flask import Flask, request, jsonify
from flask_cors import CORS
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import subprocess


def open_app(package_name: str):
    cmd = [
        "su", "-c",
        f"monkey -p {package_name} -c android.intent.category.LAUNCHER 1"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode == 0:
        print(f"已启动 {package_name}")
    else:
        print("启动失败:", result.stderr)


app = Flask(__name__)
CORS(app)

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

mapping = {}

DOWNLOAD_DIR = '/sdcard/1'
os.makedirs(DOWNLOAD_DIR, exist_ok=True)

# ===================== 更新日志相关 =====================
UPDATE_LOG_PATH = '/sdcard/更新日志.txt'

# ===================== MP4 队列 =====================
# 每行格式: filename<TAB>url
# 第二个脚本 (下载器) 会读取此文件并下载，下载成功后会从队列移除
MP4_QUEUE_PATH = '/sdcard/mp4_queue.txt'


def parse_show_episode(s):
    match = re.match(r'^([^\d]+?)(\d+)', s.strip())
    if match:
        return match.group(1).strip(), int(match.group(2))
    return None, None


def load_logged_shows():
    logged = {}
    if not os.path.exists(UPDATE_LOG_PATH):
        return logged
    try:
        with open(UPDATE_LOG_PATH, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception as e:
        logger.warning(f"读取更新日志失败: {e}")
        return logged

    pattern = re.compile(r'^(\S+)\s+(\S+)\s+(\d+\.\d+)$')
    for line in content.split("\n"):
        s = line.strip()
        if not s:
            continue
        m = pattern.match(s)
        if not m:
            continue
        show_name, ep = parse_show_episode(m.group(2))
        if show_name is None or ep is None:
            continue
        if show_name not in logged or ep > logged[show_name]:
            logged[show_name] = ep
    return logged
# ======================================================


@app.route('/decrypt', methods=['POST'])
def decrypt():
    try:
        data = request.get_json()
        if not data:
            return jsonify({'error': '无效请求'}), 400

        token = data.get('token', '')
        deviceid = data.get('deviceid', '')
        timestamp = data.get('timestamp', '')
        r_sign = data.get('r_sign', '')

        if not token:
            return jsonify({'error': '缺少 token'}), 400
        if not r_sign:
            return jsonify({'error': '缺少加密数据'}), 400

        try:
            bytes.fromhex(r_sign)
        except ValueError:
            return jsonify({'error': '加密数据格式错误'}), 400

        key = token[:32].encode('utf-8')
        if len(key) < 32:
            key = key.ljust(32, b'\0')

        iv_source = (deviceid + timestamp).encode('utf-8') if deviceid and timestamp else b'default_iv_source'
        iv_hex = hashlib.md5(iv_source).hexdigest()
        iv = bytes.fromhex(iv_hex)

        cipher = AES.new(key, AES.MODE_CBC, iv)
        encrypted_data = bytes.fromhex(r_sign)
        plaintext_padded = cipher.decrypt(encrypted_data)
        plaintext = unpad(plaintext_padded, AES.block_size)

        try:
            plaintext_str = plaintext.decode('utf-8')
        except UnicodeDecodeError:
            plaintext_str = plaintext.hex()

        return jsonify({'plaintext': plaintext_str})

    except Exception as e:
        logger.error(f"解密错误: {e}")
        return jsonify({'error': str(e)}), 500


@app.route('/store', methods=['POST'])
def store_mapping():
    """
    存储 url -> filename 映射；若为 mp4：
      1. 从 filename 解析剧名+集数
      2. 读更新日志，只有 下载集数 > 日志集数 才入队，否则跳过
      3. 不立即下载，只把链接追加到 /sdcard/mp4_queue.txt
      4. 将当前文件名写入 /sdcard/episode.txt（覆盖）
    """
    data = request.get_json()
    url = data.get('url')
    filename = data.get('filename')
    if not url or not filename:
        return jsonify({'error': 'Missing url or filename'}), 400

    mapping[url] = filename
    logger.info(f"存储映射: {url} -> {filename}")

    file_to_record = filename

    # ---------- 检测 MP4 ----------
    if '.mp4?cdn_key=' in url:
        show_name, ep = parse_show_episode(filename)
        logger.info(f"解析结果: 剧名={show_name}, 集数={ep}")

        # 更新日志校验
        if show_name and ep is not None:
            logged_shows = load_logged_shows()
            if show_name in logged_shows:
                logged_ep = logged_shows[show_name]
                if ep <= logged_ep:
                    logger.info(
                        f"⏭️  跳过入队（{show_name} 第{ep}集 ≤ 日志第{logged_ep}集）: {filename}"
                    )
                    try:
                        with open('/sdcard/episode.txt', 'w') as f:
                            f.write(filename)
                    except Exception as e:
                        logger.error(f"写入 episode.txt 失败: {e}")
                    return jsonify({
                        'success': True,
                        'skipped': True,
                        'reason': 'episode_not_greater_than_log',
                        'show': show_name,
                        'episode': ep,
                        'logged_episode': logged_ep,
                    })
                else:
                    logger.info(f"✅ 验证通过（第{ep}集 > 日志第{logged_ep}集），加入 MP4 队列")
            else:
                logger.info(f"✅ 日志中无此剧（{show_name}），加入 MP4 队列")
        else:
            logger.info(f"⚠️  无法解析剧名/集数，仍加入 MP4 队列")

        # ---------- 只保存链接到队列，不下载 ----------
        try:
            with open(MP4_QUEUE_PATH, 'a', encoding='utf-8') as f:
                f.write(f"{filename}\t{url}\n")
            logger.info(f"📥 已保存 MP4 链接到队列: {filename} -> {MP4_QUEUE_PATH}")
            file_to_record = filename
        except Exception as e:
            logger.error(f"保存 MP4 链接到队列失败: {e}")

    # ---------- 写入 episode.txt（覆盖） ----------
    episode_path = '/sdcard/episode.txt'
    try:
        with open(episode_path, 'w') as f:
            f.write(file_to_record)
        logger.info(f"写入 episode.txt: {file_to_record}")
    except Exception as e:
        logger.error(f"写入 episode.txt 失败: {e}")

    return jsonify({'success': True, 'file': file_to_record, 'queued': True})


@app.route('/get_mapping', methods=['POST'])
def get_mapping():
    data = request.get_json()
    url = data.get('url')
    if url and url in mapping:
        filename = mapping.pop(url)
        logger.info(f"查询映射: {url} -> {filename}")
        return jsonify({'filename': filename})
    return jsonify({'filename': None})


@app.route('/health', methods=['GET'])
def health():
    return jsonify({'status': 'ok'})


if __name__ == '__main__':
    # open_app("com.miniapp.AutoDownload")
    app.run(host='127.0.0.1', port=5000, debug=True)