import json
import time
from datetime import datetime
import pymysql
from flask import Flask, request, jsonify
from loguru import logger
# 引入逻辑类
from inv_img_double_search import AmazonImageSearch, SITE_CONFIG_MAPPER
from amazon_configs import site_name_secret_dict
TIMEOUT = 25  # 设置超时时间（秒）
app = Flask(__name__)

# 让 Flask 支持中文返回不乱码
app.config['JSON_AS_ASCII'] = False

DB_CONFIG = {
    'host': 'rm-wz9yg9bsb2zf01ea4yo.mysql.rds.aliyuncs.com',       # 你的数据库IP (如果是远程数据库请填写公网IP)
    'port': 3306,
    'user': 'adv_test',            # 数据库用户名
    'password': 'jBVQe0FAwZgY3YsQqfwzUd', # 数据库密码
    'db': 'selection',      # 数据库名
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}

# 获取数据库连接的辅助函数
def get_db_conn():
    return pymysql.connect(**DB_CONFIG)

@app.route('/', methods=['GET'])
def index():
    """
    首页：显示服务状态和简易文档
    """
    html_content = """
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Amazon 以图搜图服务</title>
        <style>
            body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 40px; line-height: 1.6; color: #333; }
            .container { background: #f9f9fa; padding: 30px; border-radius: 10px; border: 1px solid #e1e4e8; }
            h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
            .status { color: #27ae60; font-weight: bold; font-size: 1.2em; }
            .endpoint { background: #2c3e50; color: #fff; padding: 5px 10px; border-radius: 4px; font-family: monospace; }
            .method { background: #e67e22; color: white; padding: 2px 6px; border-radius: 3px; font-size: 0.8em; font-weight: bold; }
            pre { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 5px; overflow-x: auto; }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>📸 Amazon Image Search API</h1>
            <p>状态：<span class="status">✅ 服务正在运行 (Service is Running)</span></p>

            <h3>接口信息</h3>
            <p>URL: <span class="endpoint">/api/search_image</span> <span class="method">POST</span></p>

            <h3>请求示例 (JSON)</h3>
            <pre>
{
    "image_url": "https://m.media-amazon.com/images/I/51i3aMcjmOL._SL600_.jpg",
    "site_name": "us",     // 可选: us
    "search_mode": "default" // 可选: default, full_image
}
            </pre>

            <h3>健康检查</h3>
            <p>URL: <a href="/health">/health</a> <span class="method">GET</span></p>
        </div>
    </body>
    </html>
    """
    return html_content


# ==========================================
#  核心业务接口
# ==========================================
@app.route('/api/search_image', methods=['POST'])
def search_image_api():
    """
    接口描述：Amazon 以图搜图
    Method: POST
    """
    # 1. 获取并校验 JSON
    data = request.get_json(silent=True)
    if not data:
        return jsonify({"code": 400, "msg": "Body必须是JSON格式"}), 400

    image_url = data.get("image_url")
    site_name = data.get("site_name", "us")
    search_mode = data.get("search_mode", "default")
    if site_name not in SITE_CONFIG_MAPPER:
        return jsonify({"code": 400, "msg": "不支持的站点"}), 400

    conn = None
    task_id = None
    # ======================================================
    # 2：写入数据库 (发布任务)
    # ======================================================
    try:
        conn = get_db_conn()
        with conn.cursor() as cursor:
            now_time = datetime.now()  # 获取当前时间 mysql的时间慢20多秒
            sql = "INSERT INTO us_inv_img_result (img_url, state,created_at) VALUES (%s, 1, %s)"
            cursor.execute(sql, (image_url, now_time))
            conn.commit()
            task_id = cursor.lastrowid
            logger.info(f"任务已创建 ID: {task_id}, 等待 VPS 处理...")
    except Exception as e:
        logger.error(f"数据库写入失败，直接转入本地运行: {e}")
        # 如果数据库挂了，不直接报错，而是直接去跑本地兜底逻辑

    finally:
        if 'conn' in locals() and conn: conn.close()
    # ======================================================
    # 3. 轮询等待结果
    # ======================================================
    if task_id:
        while True:
            row = None
            try:
                conn = get_db_conn()
                with conn.cursor() as cursor:
                    # 每次必须查 state, result_data 和 created_at
                    sql = "SELECT state, result_data, created_at FROM us_inv_img_result WHERE id = %s"
                    cursor.execute(sql, (task_id,))
                    row = cursor.fetchone()
            except Exception as e:
                logger.error(f"轮询异常: {e}")
            finally:
                if 'conn' in locals() and conn: conn.close()
            # 如果任务突然查不到了，直接跳出走本地
            if not row:
                break
            state = row['state']
            created_at = row['created_at']  # 类型是 datetime
            # print(created_at,type(created_at))
            # 计算耗时 (当前时间 - 数据库里的创建时间)
            elapsed_seconds = 0
            if created_at:
                elapsed_seconds = (datetime.now() - created_at).total_seconds()
            # 情况1: 状态为 3 (已完成) -> ，返回结果
            if state == 3:
                logger.success(f"任务 {task_id} VPS完成 (耗时{elapsed_seconds:.1f}s)")
                try:
                    res_data = json.loads(row['result_data'])
                    return jsonify({"code": 200, "msg": "success", "data": res_data})
                except:
                    # 极少情况：JSON解析失败，视为失败走兜底
                    break

            # 情况2: 状态为 1 (待处理) 且 耗时超过 5秒 -> 超时兜底
            if state == 1 and elapsed_seconds > 5:
                logger.warning(f"任务 {task_id} [待处理] 超时 ({elapsed_seconds:.1f}s > 5s) -> 转本地")
                break

            # 情况3: 状态为 2 (爬取中) 且 耗时超过 30秒 -> 超时兜底
            if state == 2 and elapsed_seconds > 30:
                logger.warning(f"任务 {task_id} [进行中] 超时 ({elapsed_seconds:.1f}s > 30s) -> 转本地")
                break

            # 没超时也没完成，休息0.3秒继续查
            time.sleep(0.3)

    # ======================================================
    # 4. 本地兜底逻辑
    # ======================================================
    try:
        logger.info(f"启动本地爬虫兜底: ")
        logger.info(f"收到API请求: Site={site_name}, Mode={search_mode}, URL={image_url}")
        client = AmazonImageSearch(site_name=site_name)
        result = client.search(image_url, search_mode='default')
        # 简单检查本地是否成功
        if result.get("error") or result.get("success") == 0:
            return jsonify({"code": 500, "msg": "本地处理失败", "data": result}), 500
        if task_id:
            try:
                conn = get_db_conn()
                with conn.cursor() as cursor:
                    json_result = json.dumps(result, ensure_ascii=False)
                    finish_time = datetime.now()
                    # 更新状态为 3 (已完成)，填入结果，更新时间
                    cursor.execute(
                        "UPDATE us_inv_img_result SET state = 3, result_data = %s, updated_at = %s WHERE id = %s",
                        (json_result, finish_time, task_id)
                    )
                    conn.commit()
                    logger.info(f"本地兜底结果已保存至数据库 ID: {task_id}")

            except Exception as save_e:
                # 存库失败只记录日志，不影响给用户返回结果
                logger.error(f"本地结果回写数据库失败: {save_e}")
            finally:
                if 'conn' in locals() and conn: conn.close()
        return jsonify({"code": 200, "msg": "success", "data": result})
    except Exception as e:
        logger.error(f"本地执行出错: {e}")
        return jsonify({"code": 500, "msg": f"Server Error: {str(e)}"}), 500


@app.route('/health', methods=['GET'])
def health():
    """健康检查接口"""
    return jsonify({"status": "ok", "service": "Amazon Image Search"})


if __name__ == "__main__":
    # 启动服务
    logger.info("Flask 服务正在启动...")
    # logger.info("请访问 http://127.0.0.1:5000 查看首页")
    app.run(host='0.0.0.0', port=5000, debug=False)