"""
趨勢資料 API 路由

提供:
- 趨勢記錄查詢
- 熱門關鍵字查詢
- AI 分析報告
- Web Search API
- 手動觸發爬取
"""

import json
import logging
from datetime import date, timedelta
from flask import Blueprint, request, jsonify, render_template
from sqlalchemy import func, text

from database.trend_models import TrendRecord, TrendKeyword, TrendAnalysis, WebSearchCache
from database.manager import get_session
from services.trend_crawler_service import get_trend_crawler_service
from services.ollama_service import OllamaService
from auth import login_required

# 設定 logging
logger = logging.getLogger(__name__)

# 建立 Blueprint
trend_bp = Blueprint('trend', __name__)


# ===== 頁面路由 =====

@trend_bp.route('/trends')
@login_required
def trends_page():
    """趨勢資料頁面"""
    return render_template('trends.html', active_page='trends')


# ===== API 路由 =====

@trend_bp.route('/api/trends/records', methods=['GET'])
@login_required
def get_trend_records():
    """
    取得趨勢記錄

    Query params:
        source: 來源篩選 (google_news, ptt, dcard, youtube)
        category: 分類篩選
        date_from: 起始日期 (YYYY-MM-DD)
        date_to: 結束日期 (YYYY-MM-DD)
        days: 天數 (與 date_from/date_to 二擇一)
        limit: 筆數限制 (預設 50)
        offset: 分頁偏移
    """
    try:
        source = request.args.get('source')
        category = request.args.get('category')
        days = request.args.get('days', type=int)
        date_from = request.args.get('date_from')
        date_to = request.args.get('date_to')
        limit = min(int(request.args.get('limit', 50)), 200)
        offset = int(request.args.get('offset', 0))

        # 處理日期
        if days:
            date_from = (date.today() - timedelta(days=days)).isoformat()
            date_to = date.today().isoformat()
        else:
            date_from = date_from or (date.today() - timedelta(days=7)).isoformat()
            date_to = date_to or date.today().isoformat()

        session = get_session()
        try:
            query = session.query(TrendRecord).filter(
                TrendRecord.trend_date >= date_from,
                TrendRecord.trend_date <= date_to
            )

            if source:
                query = query.filter(TrendRecord.source == source)
            if category:
                query = query.filter(TrendRecord.category == category)

            total = query.count()
            records = query.order_by(
                TrendRecord.popularity_score.desc(),
                TrendRecord.created_at.desc()
            ).offset(offset).limit(limit).all()

            return jsonify({
                'success': True,
                'total': total,
                'limit': limit,
                'offset': offset,
                'data': [r.to_dict() for r in records]
            })
        finally:
            session.close()

    except Exception as e:
        logger.error(f"取得趨勢記錄失敗: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@trend_bp.route('/api/trends/keywords', methods=['GET'])
@login_required
def get_trend_keywords():
    """
    取得熱門關鍵字

    Query params:
        source: 來源篩選
        category: 分類篩選
        days: 天數範圍 (預設 7)
        limit: 筆數限制 (預設 30)
    """
    try:
        source = request.args.get('source')
        category = request.args.get('category')
        days = int(request.args.get('days', 7))
        limit = min(int(request.args.get('limit', 30)), 100)

        date_from = date.today() - timedelta(days=days)

        session = get_session()
        try:
            query = session.query(
                TrendKeyword.keyword,
                func.sum(TrendKeyword.mention_count).label('total_mentions'),
                func.count(TrendKeyword.source.distinct()).label('source_count')
            ).filter(
                TrendKeyword.trend_date >= date_from
            ).group_by(TrendKeyword.keyword)

            if source:
                query = query.filter(TrendKeyword.source == source)
            if category:
                query = query.filter(TrendKeyword.category == category)

            keywords = query.order_by(
                text('total_mentions DESC')
            ).limit(limit).all()

            return jsonify({
                'success': True,
                'date_range': {
                    'from': date_from.isoformat(),
                    'to': date.today().isoformat()
                },
                'data': [
                    {
                        'keyword': kw.keyword,
                        'total_mentions': kw.total_mentions,
                        'source_count': kw.source_count
                    }
                    for kw in keywords
                ]
            })
        finally:
            session.close()

    except Exception as e:
        logger.error(f"取得趨勢關鍵字失敗: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@trend_bp.route('/api/trends/analysis', methods=['GET'])
@login_required
def get_trend_analysis():
    """
    取得 AI 趨勢分析報告

    Query params:
        date: 分析日期 (預設今日)
        category: 分類篩選
        type: 分析類型 (daily_summary, weekly_trend, hot_topic)
    """
    try:
        analysis_date = request.args.get('date', date.today().isoformat())
        category = request.args.get('category')
        analysis_type = request.args.get('type', 'daily_summary')

        session = get_session()
        try:
            query = session.query(TrendAnalysis).filter(
                TrendAnalysis.analysis_date == analysis_date,
                TrendAnalysis.analysis_type == analysis_type
            )

            if category:
                query = query.filter(TrendAnalysis.category == category)
            else:
                query = query.filter(TrendAnalysis.category.is_(None))

            analysis = query.first()

            if not analysis:
                return jsonify({
                    'success': False,
                    'message': '找不到分析報告'
                }), 404

            return jsonify({
                'success': True,
                'data': analysis.to_dict()
            })
        finally:
            session.close()

    except Exception as e:
        logger.error(f"取得趨勢分析失敗: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@trend_bp.route('/api/trends/crawl', methods=['POST'])
@login_required
def trigger_trend_crawl():
    """手動觸發趨勢爬取"""
    try:
        data = request.get_json() or {}
        sources = data.get('sources')  # 可選，指定來源
        categories = data.get('categories')  # 可選，指定分類
        analyze = data.get('analyze', True)  # 是否進行 AI 分析

        service = get_trend_crawler_service()
        result = service.crawl_and_save_all(
            sources=sources,
            categories=categories,
            analyze=analyze
        )

        return jsonify({
            'success': True,
            'message': f"爬取完成: 新增 {result['new_records']} 筆記錄",
            'result': result
        })

    except Exception as e:
        logger.error(f"觸發趨勢爬取失敗: {e}")
        return jsonify({
            'success': False,
            'error': f"爬取失敗: {str(e)}"
        }), 500


@trend_bp.route('/api/trends/stats', methods=['GET'])
@login_required
def get_trend_stats():
    """取得趨勢資料統計"""
    try:
        days = int(request.args.get('days', 7))

        service = get_trend_crawler_service()
        result = service.get_trend_stats(days=days)

        return jsonify(result)

    except Exception as e:
        logger.error(f"取得趨勢統計失敗: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@trend_bp.route('/api/trends/web_search', methods=['POST'])
@login_required
def trend_web_search():
    """
    使用 Ollama Web Search 搜尋趨勢

    Request body:
        query: 搜尋查詢
        search_type: 搜尋類型 (general, news, shopping, trends)
        use_cache: 是否使用快取 (預設 true)
        cache_hours: 快取時間 (預設 24)
    """
    try:
        data = request.get_json() or {}
        query = data.get('query', '').strip()
        search_type = data.get('search_type', 'trends')
        use_cache = data.get('use_cache', True)
        cache_hours = data.get('cache_hours', 24)

        if not query:
            return jsonify({'success': False, 'error': '請輸入搜尋關鍵字'}), 400

        service = get_trend_crawler_service()

        if use_cache:
            result = service.web_search_with_cache(query, search_type, cache_hours)
        else:
            # 直接呼叫 Ollama
            ollama = OllamaService()
            response = ollama.web_search(query, search_type=search_type)

            if response.success:
                try:
                    content = response.content
                    json_start = content.find('{')
                    json_end = content.rfind('}') + 1
                    if json_start >= 0 and json_end > json_start:
                        parsed = json.loads(content[json_start:json_end])
                    else:
                        parsed = {'raw': content}
                except json.JSONDecodeError:
                    parsed = {'raw': response.content}

                result = {
                    'success': True,
                    'cached': False,
                    'data': {
                        'query': query,
                        'search_type': search_type,
                        'result': parsed,
                        'model': response.model,
                        'duration': response.total_duration
                    }
                }
            else:
                result = {
                    'success': False,
                    'error': response.error
                }

        if result['success']:
            return jsonify(result)
        else:
            return jsonify(result), 500

    except Exception as e:
        logger.error(f"趨勢 Web Search 失敗: {e}")
        return jsonify({
            'success': False,
            'error': f'搜尋失敗: {str(e)}'
        }), 500


@trend_bp.route('/api/trends/category_insights', methods=['GET'])
@login_required
def get_category_insights():
    """
    取得分類趨勢洞察 (結合 Web Search)

    Query params:
        category: 商品分類
    """
    try:
        category = request.args.get('category', '美妝')

        service = get_trend_crawler_service()
        insights = service.search_trends_for_category(category)

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

    except Exception as e:
        logger.error(f"取得分類洞察失敗: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@trend_bp.route('/api/trends/sources', methods=['GET'])
@login_required
def get_trend_sources():
    """取得可用的趨勢來源列表"""
    return jsonify({
        'success': True,
        'data': {
            'sources': [
                {'code': 'google_news', 'name': 'Google 新聞', 'icon': 'newspaper'},
                {'code': 'ptt', 'name': 'PTT', 'icon': 'comments'},
                {'code': 'dcard', 'name': 'Dcard', 'icon': 'mobile'},
                {'code': 'youtube', 'name': 'YouTube', 'icon': 'youtube'},
                {'code': 'ollama_web_search', 'name': 'AI 搜尋', 'icon': 'robot'},
            ],
            'categories': [
                {'code': '美妝', 'name': '美妝'},
                {'code': '3C', 'name': '3C'},
                {'code': '服飾', 'name': '服飾'},
                {'code': '居家', 'name': '居家'},
                {'code': '電商', 'name': '電商'},
                {'code': '優惠', 'name': '優惠'},
                {'code': '母嬰', 'name': '母嬰'},
                {'code': '美食', 'name': '美食'},
                {'code': '熱門', 'name': '熱門話題'},
            ]
        }
    })


@trend_bp.route('/api/trends/cache/clear', methods=['POST'])
@login_required
def clear_trend_cache():
    """清除過期的 Web Search 快取"""
    try:
        session = get_session()
        try:
            # 刪除過期快取
            deleted = session.query(WebSearchCache).filter(
                WebSearchCache.expires_at < datetime.now()
            ).delete()

            session.commit()

            return jsonify({
                'success': True,
                'message': f'已清除 {deleted} 筆過期快取'
            })
        finally:
            session.close()

    except Exception as e:
        logger.error(f"清除快取失敗: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


# 匯入 datetime 用於清除快取
from datetime import datetime
