#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Bot API 路由模組
提供給 Clawdbot/Telegram Bot 使用的 API 端點
使用 API Token 認證，不需要 session
"""

import os
from datetime import datetime, timezone, timedelta
from functools import wraps
from flask import Blueprint, request, jsonify
from sqlalchemy import func, desc, text

from config import BASE_DIR
from database.manager import DatabaseManager
from services.logger_manager import SystemLogger

# 時區設定
TAIPEI_TZ = timezone(timedelta(hours=8))

# Logger
sys_log = SystemLogger("BotAPI").get_logger()

# Blueprint 定義
bot_api_bp = Blueprint('bot_api', __name__)

# API Token (從環境變數讀取，無預設值)
BOT_API_TOKEN = os.getenv('BOT_API_TOKEN')
if not BOT_API_TOKEN:
    import logging as _log
    _log.warning("[BotAPI] BOT_API_TOKEN 未設定，Bot API 端點將拒絕所有請求")


def require_api_token(f):
    """API Token 認證裝飾器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 從 header 或 query string 取得 token
        token = request.headers.get('X-API-Token') or request.args.get('token')

        if not token:
            return jsonify({
                'success': False,
                'error': 'Missing API token'
            }), 401

        if token != BOT_API_TOKEN:
            sys_log.warning(f"[BotAPI] Invalid token attempt from {request.remote_addr}")
            return jsonify({
                'success': False,
                'error': 'Invalid API token'
            }), 403

        return f(*args, **kwargs)
    return decorated_function


@bot_api_bp.route('/bot/api/status')
def bot_api_status():
    """API 狀態檢查（不需要認證）"""
    return jsonify({
        'success': True,
        'service': 'MOMO Pro Bot API',
        'version': '1.0.0',
        'timestamp': datetime.now(TAIPEI_TZ).isoformat()
    })


@bot_api_bp.route('/bot/api/daily_sales')
@require_api_token
def bot_daily_sales():
    """
    查詢每日業績

    Query Parameters:
    - date: 日期 (YYYY-MM-DD)，預設今天

    Returns:
    - 業績總額、訂單數、商品數等統計
    """
    try:
        date_str = request.args.get('date')

        if date_str:
            try:
                query_date = datetime.strptime(date_str, '%Y-%m-%d').date()
            except ValueError:
                return jsonify({
                    'success': False,
                    'error': f'Invalid date format: {date_str}. Use YYYY-MM-DD'
                }), 400
        else:
            query_date = datetime.now(TAIPEI_TZ).date()

        db = DatabaseManager()
        engine = db.engine

        # 查詢當日業績
        query = text("""
            SELECT
                COUNT(*) as total_records,
                COALESCE(SUM(CAST("總業績" AS FLOAT)), 0) as total_revenue,
                COUNT(DISTINCT "訂單編號") as order_count,
                COUNT(DISTINCT "商品ID") as product_count
            FROM daily_sales_snapshot
            WHERE "日期" = :query_date
        """)

        with engine.connect() as conn:
            result = conn.execute(query, {'query_date': str(query_date)})
            row = result.fetchone()

        if row and row[0] > 0:
            return jsonify({
                'success': True,
                'date': str(query_date),
                'data': {
                    'total_records': row[0],
                    'total_revenue': round(row[1], 2),
                    'order_count': row[2],
                    'product_count': row[3],
                    'formatted_revenue': f"${row[1]:,.0f}"
                }
            })
        else:
            return jsonify({
                'success': True,
                'date': str(query_date),
                'data': None,
                'message': f'No sales data for {query_date}'
            })

    except Exception as e:
        sys_log.error(f"[BotAPI] daily_sales error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/sales_summary')
@require_api_token
def bot_sales_summary():
    """
    查詢業績摘要（今日 vs 昨日 vs 上週同日）

    Returns:
    - 今日、昨日、上週同日的業績比較
    """
    try:
        today = datetime.now(TAIPEI_TZ).date()
        yesterday = today - timedelta(days=1)
        last_week = today - timedelta(days=7)

        db = DatabaseManager()
        engine = db.engine

        def get_daily_revenue(date):
            query = text("""
                SELECT COALESCE(SUM(CAST("總業績" AS FLOAT)), 0)
                FROM daily_sales_snapshot
                WHERE "日期" = :query_date
            """)
            with engine.connect() as conn:
                result = conn.execute(query, {'query_date': str(date)})
                row = result.fetchone()
                return row[0] if row else 0

        today_revenue = get_daily_revenue(today)
        yesterday_revenue = get_daily_revenue(yesterday)
        last_week_revenue = get_daily_revenue(last_week)

        # 計算成長率
        dod_growth = ((today_revenue - yesterday_revenue) / yesterday_revenue * 100) if yesterday_revenue > 0 else 0
        wow_growth = ((today_revenue - last_week_revenue) / last_week_revenue * 100) if last_week_revenue > 0 else 0

        return jsonify({
            'success': True,
            'data': {
                'today': {
                    'date': str(today),
                    'revenue': round(today_revenue, 2),
                    'formatted': f"${today_revenue:,.0f}"
                },
                'yesterday': {
                    'date': str(yesterday),
                    'revenue': round(yesterday_revenue, 2),
                    'formatted': f"${yesterday_revenue:,.0f}"
                },
                'last_week': {
                    'date': str(last_week),
                    'revenue': round(last_week_revenue, 2),
                    'formatted': f"${last_week_revenue:,.0f}"
                },
                'growth': {
                    'dod': round(dod_growth, 2),  # Day over Day
                    'wow': round(wow_growth, 2),  # Week over Week
                    'dod_emoji': '📈' if dod_growth > 0 else ('📉' if dod_growth < 0 else '➡️'),
                    'wow_emoji': '📈' if wow_growth > 0 else ('📉' if wow_growth < 0 else '➡️')
                }
            }
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] sales_summary error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/stockout')
@require_api_token
def bot_stockout():
    """
    查詢缺貨商品

    Query Parameters:
    - status: pending/sent/all (預設 pending)
    - limit: 數量限制 (預設 10)

    Returns:
    - 缺貨商品清單
    """
    try:
        status = request.args.get('status', 'pending')
        limit = min(int(request.args.get('limit', 10)), 50)  # 最多 50 筆

        db = DatabaseManager()
        engine = db.engine

        # 根據狀態查詢
        if status == 'all':
            status_condition = ""
        elif status == 'sent':
            status_condition = "WHERE sent_date IS NOT NULL"
        else:  # pending
            status_condition = "WHERE sent_date IS NULL"

        query = text(f"""
            SELECT
                id, vendor_name, product_code, product_name,
                current_stock, stockout_days, created_at, sent_date
            FROM vendor_stockout
            {status_condition}
            ORDER BY created_at DESC
            LIMIT :limit
        """)

        with engine.connect() as conn:
            result = conn.execute(query, {'limit': limit})
            rows = result.fetchall()

        items = []
        for row in rows:
            items.append({
                'id': row[0],
                'vendor_name': row[1],
                'product_code': row[2],
                'product_name': row[3],
                'current_stock': row[4],
                'stockout_days': row[5],
                'created_at': str(row[6]) if row[6] else None,
                'sent': row[7] is not None
            })

        return jsonify({
            'success': True,
            'status_filter': status,
            'count': len(items),
            'data': items
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] stockout error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/product_search')
@require_api_token
def bot_product_search():
    """
    搜尋商品

    Query Parameters:
    - q: 搜尋關鍵字（商品名稱或貨號）
    - limit: 數量限制 (預設 10)

    Returns:
    - 符合的商品清單
    """
    try:
        keyword = request.args.get('q', '').strip()
        limit = min(int(request.args.get('limit', 10)), 20)

        if not keyword:
            return jsonify({
                'success': False,
                'error': 'Missing search keyword (q parameter)'
            }), 400

        db = DatabaseManager()
        engine = db.engine

        # 查詢商品並取得最新價格
        query = text("""
            SELECT
                p.id, p.i_code, p.name, pr.price as current_price,
                p.status, p.category, p.updated_at
            FROM products p
            LEFT JOIN LATERAL (
                SELECT price FROM price_records
                WHERE product_id = p.id
                ORDER BY timestamp DESC
                LIMIT 1
            ) pr ON true
            WHERE p.name ILIKE :keyword OR p.i_code ILIKE :keyword
            ORDER BY p.updated_at DESC
            LIMIT :limit
        """)

        with engine.connect() as conn:
            result = conn.execute(query, {
                'keyword': f'%{keyword}%',
                'limit': limit
            })
            rows = result.fetchall()

        items = []
        for row in rows:
            items.append({
                'id': row[0],
                'i_code': row[1],
                'name': row[2],
                'current_price': row[3],
                'status': row[4],
                'category': row[5],
                'updated_at': str(row[6]) if row[6] else None
            })

        return jsonify({
            'success': True,
            'keyword': keyword,
            'count': len(items),
            'data': items
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] product_search error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/top_products')
@require_api_token
def bot_top_products():
    """
    查詢熱銷商品

    Query Parameters:
    - date: 日期 (YYYY-MM-DD)，預設今天
    - limit: 數量限制 (預設 10)

    Returns:
    - 熱銷商品排行
    """
    try:
        date_str = request.args.get('date')
        limit = min(int(request.args.get('limit', 10)), 20)

        if date_str:
            try:
                query_date = datetime.strptime(date_str, '%Y-%m-%d').date()
            except ValueError:
                return jsonify({
                    'success': False,
                    'error': f'Invalid date format: {date_str}. Use YYYY-MM-DD'
                }), 400
        else:
            query_date = datetime.now(TAIPEI_TZ).date()

        db = DatabaseManager()
        engine = db.engine

        query = text("""
            SELECT
                "商品ID",
                "商品名稱",
                SUM(CAST("總業績" AS FLOAT)) as total_revenue,
                SUM(CAST("數量" AS INTEGER)) as total_quantity
            FROM daily_sales_snapshot
            WHERE "日期" = :query_date
            GROUP BY "商品ID", "商品名稱"
            ORDER BY total_revenue DESC
            LIMIT :limit
        """)

        with engine.connect() as conn:
            result = conn.execute(query, {
                'query_date': str(query_date),
                'limit': limit
            })
            rows = result.fetchall()

        items = []
        for i, row in enumerate(rows, 1):
            items.append({
                'rank': i,
                'product_code': row[0],
                'product_name': row[1],
                'total_revenue': round(row[2], 2),
                'total_quantity': row[3],
                'formatted_revenue': f"${row[2]:,.0f}"
            })

        return jsonify({
            'success': True,
            'date': str(query_date),
            'count': len(items),
            'data': items
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] top_products error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


# ===== AI 助手 API =====

@bot_api_bp.route('/bot/api/ai/status')
@require_api_token
def bot_ai_status():
    """
    查詢 AI 服務狀態

    Returns:
    - Ollama 和 Gemini 的連線狀態
    """
    try:
        from services.ai_provider import get_ai_status
        status = get_ai_status(force_refresh=True)

        return jsonify({
            'success': True,
            'data': {
                'default_provider': status.get('default_provider', 'ollama'),
                'ollama': {
                    'connected': status.get('ollama', {}).get('connected', False),
                    'model': status.get('ollama', {}).get('model', 'unknown')
                },
                'gemini': {
                    'connected': status.get('gemini', {}).get('connected', False),
                    'model': status.get('gemini', {}).get('model', 'unknown')
                }
            }
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] ai_status error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/ai/generate_copy', methods=['POST'])
@require_api_token
def bot_generate_copy():
    """
    生成銷售文案

    Request JSON:
    - product_name: 商品名稱 (必填)
    - trend_keywords: 趨勢關鍵字 (選填, 陣列)
    - style: 文案風格 (選填, 預設 '吸睛')
    - provider: AI 提供者 (選填；一律 Ollama-first，Gemini 僅作失敗備援)

    Returns:
    - 生成的銷售文案
    """
    try:
        data = request.get_json() or {}
        product_name = data.get('product_name', '')
        trend_keywords = data.get('trend_keywords', [])
        style = data.get('style', '吸睛')
        provider = data.get('provider', None)

        if not product_name:
            return jsonify({
                'success': False,
                'error': 'Missing product_name'
            }), 400

        from services.ai_provider import ai_provider_service

        result = ai_provider_service.generate_sales_copy(
            product_name=product_name,
            provider=provider,
            trend_keywords=trend_keywords,
            style=style
        )

        if result.success:
            return jsonify({
                'success': True,
                'data': {
                    'copy': result.content,
                    'model': result.model,
                    'provider': result.provider,
                    'duration': round(result.total_duration, 2) if result.total_duration else None
                }
            })
        else:
            return jsonify({
                'success': False,
                'error': result.error
            }), 500

    except Exception as e:
        sys_log.error(f"[BotAPI] generate_copy error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/ai/trends')
@require_api_token
def bot_ai_trends():
    """
    查詢趨勢資料

    Query Parameters:
    - categories: 分類 (選填, 可多個)
    - time_range: 時間範圍 day/week/month (預設 week)

    Returns:
    - 新聞、社群熱門話題、關鍵字
    """
    try:
        from services.trend_crawler import TrendCrawler

        categories = request.args.getlist('categories') or ['時尚美妝', '生活居家', '健康保健']
        time_range = request.args.get('time_range', 'week')

        if time_range not in ['day', 'week', 'month']:
            time_range = 'week'

        trend_crawler = TrendCrawler()
        trend_data = trend_crawler.get_all_trends(
            categories=categories,
            time_range=time_range,
            include_social=True
        )

        # 簡化輸出供 Bot 使用
        result = {
            'timestamp': trend_data.timestamp.isoformat(),
            'time_range': time_range,
            'keywords': trend_data.keywords[:10],
            'news': [
                {
                    'title': n.title,
                    'source': n.source,
                    'category': n.category
                }
                for n in trend_data.news_items[:10]
            ],
            'social': [
                {
                    'title': p.title,
                    'source': p.source,
                    'likes': p.likes
                }
                for p in trend_data.social_posts[:10]
            ]
        }

        return jsonify({
            'success': True,
            'data': result
        })

    except Exception as e:
        sys_log.error(f"[BotAPI] ai_trends error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/ai/weather')
@require_api_token
def bot_ai_weather():
    """
    查詢天氣資訊

    Query Parameters:
    - location: 地點 (預設 臺北市)

    Returns:
    - 天氣資訊和行銷建議
    """
    try:
        from services.trend_crawler import TrendCrawler

        location = request.args.get('location', '臺北市')

        trend_crawler = TrendCrawler()
        weather = trend_crawler.fetch_weather(location)

        if weather:
            return jsonify({
                'success': True,
                'data': {
                    'location': weather.location,
                    'date': weather.date,
                    'description': weather.weather_description,
                    'temp_range': f"{weather.min_temp}°C ~ {weather.max_temp}°C",
                    'rain_probability': weather.rain_probability,
                    'humidity': weather.humidity,
                    'marketing_suggestions': weather.marketing_suggestions
                }
            })
        else:
            return jsonify({
                'success': False,
                'error': '無法獲取天氣資訊'
            }), 500

    except Exception as e:
        sys_log.error(f"[BotAPI] ai_weather error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@bot_api_bp.route('/bot/api/ai/suggest', methods=['POST'])
@require_api_token
def bot_ai_suggest():
    """
    生成銷售策略建議

    Request JSON:
    - product_name: 商品名稱 (必填)
    - trend_keywords: 趨勢關鍵字 (選填)

    Returns:
    - 銷售策略建議
    """
    try:
        data = request.get_json() or {}
        product_name = data.get('product_name', '')
        trend_keywords = data.get('trend_keywords', [])

        if not product_name:
            return jsonify({
                'success': False,
                'error': 'Missing product_name'
            }), 400

        from services.ollama_service import OllamaService

        ollama_service = OllamaService()

        system_prompt = """你是一位資深電商銷售策略顧問，專精於台灣市場。
請用繁體中文回答，簡潔明瞭。"""

        context = f"熱門趨勢：{', '.join(trend_keywords)}" if trend_keywords else "無特定趨勢"

        prompt = f"""請為「{product_name}」提供簡短銷售建議：

市場資訊：{context}

請提供：
1. 目標客群（一句話）
2. 主打賣點（一句話）
3. 促銷建議（一句話）

請簡潔回答，總共不超過 100 字。"""

        result = ollama_service.generate(prompt, system_prompt=system_prompt, temperature=0.6)

        if result.success:
            return jsonify({
                'success': True,
                'data': {
                    'suggestion': result.content,
                    'model': result.model,
                    'duration': round(result.total_duration, 2) if result.total_duration else None
                }
            })
        else:
            return jsonify({
                'success': False,
                'error': result.error
            }), 500

    except Exception as e:
        sys_log.error(f"[BotAPI] ai_suggest error: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


# ===== 降價決策通知 =====

@bot_api_bp.route('/bot/api/price-decision/notify', methods=['POST'])
@require_api_token
def price_decision_notify():
    """
    觸發 Telegram 降價決策通知（推送給所有 is_admin=True 的用戶）

    Request JSON:
    - product_sku: 商品貨號（必填）
    - product_name: 商品名稱（必填）
    - current_price: 現價（數字，必填）
    - suggested_price: 建議降至（數字，必填）
    - reason: AI 理由（必填）
    - insight_id: ai_insights 表的 ID（必填，供回調按鈕使用）
    - report_url: 分析報表連結（選填）
    """
    from sqlalchemy import text as sa_text

    data = request.get_json() or {}
    required_fields = ['product_sku', 'product_name', 'current_price', 'suggested_price', 'reason', 'insight_id']
    missing = [f for f in required_fields if data.get(f) is None]
    if missing:
        return jsonify({'success': False, 'error': f'Missing fields: {", ".join(missing)}'}), 400

    product_sku = data['product_sku']
    product_name = data['product_name']
    insight_id = int(data['insight_id'])
    report_url = data.get('report_url', '')

    try:
        current_price = float(data['current_price'])
        suggested_price = float(data['suggested_price'])
    except (ValueError, TypeError) as e:
        return jsonify({'success': False, 'error': f'Invalid price value: {e}'}), 400

    token = os.getenv('TELEGRAM_BOT_TOKEN')
    if not token:
        return jsonify({'success': False, 'error': 'TELEGRAM_BOT_TOKEN not configured'}), 500

    from services.telegram_templates import price_decision, send_telegram_with_result
    message, keyboard = price_decision(
        product_name=product_name,
        product_sku=product_sku,
        current_price=current_price,
        suggested_price=suggested_price,
        reason=data['reason'],
        insight_id=insight_id,
        report_url=report_url or None,
    )

    db = DatabaseManager()
    sent_count = 0
    errors = []

    try:
        with db.engine.connect() as conn:
            rows = conn.execute(sa_text(
                "SELECT telegram_id FROM telegram_users WHERE is_active = true AND is_admin = true"
            )).fetchall()
    except Exception as e:
        sys_log.error(f"[BotAPI] price_decision_notify DB error: {e}")
        return jsonify({'success': False, 'error': f'DB error: {e}'}), 500

    admin_chat_ids = [row[0] for row in rows]
    if admin_chat_ids:
        result = send_telegram_with_result(
            message,
            chat_ids=admin_chat_ids,
            reply_markup=keyboard,
            parse_mode="HTML",
        )
        sent_count = int(result.get("sent", 0))
        errors = list(result.get("errors", []))

    sys_log.info(f"[BotAPI] price_decision_notify sent={sent_count}/{len(rows)} insight_id={insight_id}")
    return jsonify({
        'success': True,
        'insight_id': insight_id,
        'sent': sent_count,
        'total_admins': len(rows),
        'errors': errors,
    })
