#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Google Gemini AI 服務模組
負責與 Google Gemini API 互動，提供文案生成、關鍵字提取等功能
支援 gemini-1.5-flash, gemini-2.5-flash, gemini-2.5-pro 模型
"""

import os
import time
import logging
from typing import Optional, Dict, Any, List
from dataclasses import dataclass, field
from datetime import date
from services.gemini_guard import (
    gemini_disabled_message,
    get_gemini_api_key,
    is_gemini_fallback_enabled,
)

logger = logging.getLogger(__name__)

# Gemini 設定 - 支援環境變數覆蓋；API key 一律透過 gemini_guard 取得
DEFAULT_GEMINI_MODEL = os.getenv('GEMINI_MODEL', 'gemini-1.5-flash')
GEMINI_TIMEOUT = int(os.getenv('GEMINI_TIMEOUT', '60'))  # 秒

# Gemini 定價 (USD per 1M tokens) - 2024/2025 定價
GEMINI_PRICING = {
    'gemini-1.5-flash': {'input': 0.075, 'output': 0.30},
    'gemini-1.5-flash-latest': {'input': 0.075, 'output': 0.30},
    'gemini-1.5-pro': {'input': 1.25, 'output': 5.00},
    'gemini-1.5-pro-latest': {'input': 1.25, 'output': 5.00},
    'gemini-2.5-flash': {'input': 0.10, 'output': 0.40},
    'gemini-2.5-flash-preview-05-20': {'input': 0.10, 'output': 0.40},
    'gemini-2.5-pro': {'input': 1.25, 'output': 10.00},
    'gemini-2.5-pro-preview-05-06': {'input': 1.25, 'output': 10.00},
}

# 可選模型清單（供 UI 選擇）
AVAILABLE_GEMINI_MODELS = [
    {'id': 'gemini-1.5-flash', 'name': 'Gemini 1.5 Flash', 'description': '最便宜、速度快'},
    {'id': 'gemini-2.5-flash', 'name': 'Gemini 2.5 Flash', 'description': '性價比最佳'},
    {'id': 'gemini-2.5-pro', 'name': 'Gemini 2.5 Pro', 'description': '最強大、高品質'},
]


@dataclass
class GeminiResponse:
    """Gemini 回應結構"""
    success: bool
    content: str
    model: str
    error: Optional[str] = None
    total_duration: Optional[float] = None
    input_tokens: int = 0
    output_tokens: int = 0
    total_tokens: int = 0
    input_cost: float = 0.0
    output_cost: float = 0.0
    total_cost: float = 0.0


class GeminiService:
    """Google Gemini AI 服務"""

    # 連線狀態快取
    _connection_cache = {'status': None, 'timestamp': 0, 'models': []}
    _CACHE_TTL = 300  # 快取 5 分鐘

    def __init__(self, api_key: str = None, model: str = None):
        """
        初始化 Gemini 服務

        Args:
            api_key: Google API Key（預設從環境變數取得）
            model: 預設模型（預設 gemini-1.5-flash）
        """
        self.api_key = api_key or get_gemini_api_key("gemini_service")
        self.model = model or DEFAULT_GEMINI_MODEL
        self._client = None
        self._initialized = False

    def _ensure_initialized(self) -> bool:
        """確保 SDK 已初始化"""
        if self._initialized:
            return True

        if not is_gemini_fallback_enabled("gemini_service"):
            logger.info(gemini_disabled_message("gemini_service"))
            return False

        if not self.api_key:
            self.api_key = get_gemini_api_key("gemini_service")

        if not self.api_key:
            logger.warning("Gemini API Key 未設定")
            return False

        try:
            import google.generativeai as genai
            genai.configure(api_key=self.api_key)
            self._initialized = True
            logger.info("Gemini SDK 初始化成功")
            return True
        except ImportError:
            logger.error("請安裝 google-generativeai: pip install google-generativeai")
            return False
        except Exception as e:
            logger.error(f"Gemini SDK 初始化失敗: {e}")
            return False

    def check_connection(self) -> bool:
        """檢查 Gemini 服務是否可用（含快取）"""
        now = time.time()

        # 使用快取避免頻繁檢查
        if (GeminiService._connection_cache['status'] is not None and
            now - GeminiService._connection_cache['timestamp'] < GeminiService._CACHE_TTL):
            return GeminiService._connection_cache['status']

        if not self._ensure_initialized():
            GeminiService._connection_cache = {'status': False, 'timestamp': now, 'models': []}
            return False

        try:
            import google.generativeai as genai

            # 嘗試列出模型驗證連線
            models = list(genai.list_models())
            available_models = [m.name for m in models if 'generateContent' in m.supported_generation_methods]

            logger.info(f"Gemini 連線成功，可用模型數: {len(available_models)}")
            GeminiService._connection_cache = {
                'status': True,
                'timestamp': now,
                'models': available_models
            }
            return True

        except Exception as e:
            logger.error(f"Gemini 連線失敗: {e}")
            GeminiService._connection_cache = {'status': False, 'timestamp': now, 'models': []}
            return False

    def list_models(self) -> List[Dict]:
        """列出可用模型（供 UI 選擇）"""
        return AVAILABLE_GEMINI_MODELS

    @staticmethod
    def calculate_cost(model: str, input_tokens: int, output_tokens: int) -> Dict[str, float]:
        """
        計算 API 費用 (USD)

        Args:
            model: 模型名稱
            input_tokens: 輸入 token 數量
            output_tokens: 輸出 token 數量

        Returns:
            dict: {'input_cost': float, 'output_cost': float, 'total_cost': float}
        """
        # 查找定價（支援完整模型名稱和簡短名稱）
        pricing = None
        for model_key, price in GEMINI_PRICING.items():
            if model_key in model or model in model_key:
                pricing = price
                break

        if not pricing:
            # 使用預設定價（最便宜的）
            pricing = GEMINI_PRICING.get('gemini-1.5-flash', {'input': 0.075, 'output': 0.30})

        # 計算費用（per 1M tokens）
        input_cost = (input_tokens / 1_000_000) * pricing['input']
        output_cost = (output_tokens / 1_000_000) * pricing['output']
        total_cost = input_cost + output_cost

        return {
            'input_cost': round(input_cost, 6),
            'output_cost': round(output_cost, 6),
            'total_cost': round(total_cost, 6)
        }

    def generate(self, prompt: str, model: str = None,
                 system_prompt: str = None, temperature: float = 0.7,
                 timeout: int = None) -> GeminiResponse:
        """
        生成文字

        Args:
            prompt: 使用者提示
            model: 模型名稱（預設使用 self.model）
            system_prompt: 系統提示
            temperature: 創意度 (0-2)
            timeout: 自訂超時時間（秒）

        Returns:
            GeminiResponse
        """
        model_name = model or self.model
        request_timeout = timeout or GEMINI_TIMEOUT

        if not is_gemini_fallback_enabled("gemini_service.generate"):
            return GeminiResponse(
                success=False,
                content='',
                model=model_name,
                error=gemini_disabled_message("gemini_service.generate")
            )

        if not self._ensure_initialized():
            return GeminiResponse(
                success=False,
                content='',
                model=model_name,
                error="Gemini SDK 未初始化，請檢查 API Key"
            )

        try:
            import google.generativeai as genai

            start_time = time.time()

            # 建立模型
            generation_config = genai.types.GenerationConfig(
                temperature=temperature,
                max_output_tokens=2048,
            )

            gen_model = genai.GenerativeModel(
                model_name=model_name,
                generation_config=generation_config,
                system_instruction=system_prompt if system_prompt else None
            )

            logger.info(f"[Gemini] 開始生成，模型: {model_name}，超時: {request_timeout}秒")

            # 生成內容
            response = gen_model.generate_content(
                prompt,
                request_options={'timeout': request_timeout}
            )

            end_time = time.time()
            duration = end_time - start_time

            # 解析回應
            content = response.text if response.text else ''

            # 取得 token 用量
            input_tokens = 0
            output_tokens = 0
            if hasattr(response, 'usage_metadata'):
                input_tokens = getattr(response.usage_metadata, 'prompt_token_count', 0)
                output_tokens = getattr(response.usage_metadata, 'candidates_token_count', 0)

            # 計算費用
            costs = self.calculate_cost(model_name, input_tokens, output_tokens)

            logger.info(f"[Gemini] 生成完成，耗時: {duration:.2f}秒，"
                       f"tokens: {input_tokens}+{output_tokens}={input_tokens+output_tokens}，"
                       f"費用: ${costs['total_cost']:.6f}")

            return GeminiResponse(
                success=True,
                content=content,
                model=model_name,
                total_duration=duration,
                input_tokens=input_tokens,
                output_tokens=output_tokens,
                total_tokens=input_tokens + output_tokens,
                input_cost=costs['input_cost'],
                output_cost=costs['output_cost'],
                total_cost=costs['total_cost']
            )

        except Exception as e:
            logger.error(f"Gemini 生成錯誤: {e}")
            return GeminiResponse(
                success=False,
                content='',
                model=model_name,
                error=str(e)
            )

    def generate_sales_copy(self, product_name: str, trend_keywords: List[str] = None,
                           style: str = "吸睛", upcoming_holidays: List[Dict] = None,
                           bestseller_products: List[Dict] = None,
                           model: str = None) -> GeminiResponse:
        """
        生成銷售文案

        Args:
            product_name: 商品名稱
            trend_keywords: 相關趨勢關鍵字
            style: 文案風格 (吸睛/專業/溫馨/急迫)
            upcoming_holidays: 即將到來的假期
            bestseller_products: 競品熱銷商品
            model: 指定模型（預設使用 self.model）

        Returns:
            GeminiResponse
        """
        style_prompts = {
            "吸睛": "使用吸引眼球的標題和表情符號",
            "專業": "使用專業術語，強調成分和功效",
            "溫馨": "使用溫暖的語氣，強調呵護和關愛",
            "急迫": "使用限時優惠的語氣，創造緊迫感"
        }

        # 趨勢關鍵字
        trend_context = ""
        if trend_keywords:
            trend_context = f"\n目前的熱門趨勢關鍵字：{', '.join(trend_keywords)}。請嘗試將這些趨勢融入文案中。"

        # 即將到來的假期
        holiday_context = ""
        if upcoming_holidays:
            holidays_text = []
            for h in upcoming_holidays[:3]:
                name = h.get('name', '')
                days = h.get('days_until', 0)
                if days == 0:
                    holidays_text.append(f"{name}（今天）")
                elif days == 1:
                    holidays_text.append(f"{name}（明天）")
                else:
                    holidays_text.append(f"{name}（{days}天後）")
            if holidays_text:
                holiday_context = f"\n即將到來的假期：{', '.join(holidays_text)}。可以考慮結合節慶氛圍或送禮情境。"

        # 競品熱銷參考
        bestseller_context = ""
        if bestseller_products:
            products_text = [f"{p.get('name', '')}（${p.get('price', '')}）" for p in bestseller_products[:3]]
            if products_text:
                bestseller_context = f"\n市場熱銷參考：{', '.join(products_text)}。可參考熱銷趨勢但要突出自家商品特色。"

        system_prompt = """你是一位專業的電商銷售文案寫手和行銷策略專家，專門為台灣電商平台撰寫商品文案。
你的文案特點：
- 使用繁體中文
- 善用表情符號增加吸引力
- 強調商品賣點和消費者利益
- 適時使用行動呼籲 (CTA)
- 若有即將到來的節日，可適度融入節慶元素
- 提供完整的行銷建議"""

        prompt = f"""請為以下商品撰寫完整的銷售文案套組：

商品名稱：{product_name}

文案風格：{style_prompts.get(style, style_prompts['吸睛'])}
{trend_context}{holiday_context}{bestseller_context}

請按照以下格式生成完整的銷售文案套組：

【大標題】
（15字以內的主打標語，吸引眼球，適合用於廣告Banner）

【中標題】
（30字以內的副標題，補充說明賣點）

【小標題】
（20字以內的精簡標語，適合用於社群貼文）

【詳細文案】
（100-150字的完整銷售文案，包含商品特色、使用情境、行動呼籲）

【推廣建議】
• 社群推廣：（Facebook/Instagram/LINE 等社群平台的建議策略）
• 影音內容：（短影音/直播/開箱影片等建議）
• 其他建議：（EDM、部落格、KOL合作等專業建議）

請確保所有內容使用繁體中文，風格一致，並突出商品價值："""

        return self.generate(
            prompt,
            model=model,
            system_prompt=system_prompt,
            temperature=0.8,
            timeout=90
        )

    def extract_keywords(self, text: str, max_keywords: int = 10,
                        model: str = None) -> GeminiResponse:
        """
        從文字中提取關鍵字

        Args:
            text: 要分析的文字
            max_keywords: 最大關鍵字數量
            model: 指定模型

        Returns:
            GeminiResponse（content 為逗號分隔的關鍵字）
        """
        system_prompt = "你是一位關鍵字提取專家。請從給定的文字中提取最重要的關鍵字。"

        prompt = f"""請從以下文字中提取最多 {max_keywords} 個關鍵字，這些關鍵字應該能代表文章的主題和重點。

文字內容：
{text}

請只輸出關鍵字，用逗號分隔，不要輸出其他內容："""

        return self.generate(prompt, model=model, system_prompt=system_prompt, temperature=0.3)

    def search_product_insights(self, product_name: str,
                                include_competitors: bool = True,
                                include_trends: bool = True,
                                model: str = None) -> GeminiResponse:
        """
        搜尋商品相關的市場洞察

        Args:
            product_name: 商品名稱
            include_competitors: 是否包含競品分析
            include_trends: 是否包含趨勢分析
            model: 指定模型

        Returns:
            GeminiResponse
        """
        system_prompt = """你是一位資深的電商市場分析師，專精於台灣市場。
你擅長分析商品的市場定位、競爭對手、以及銷售趨勢。
請提供全面但簡潔的市場洞察，使用繁體中文。"""

        analysis_parts = ["市場定位分析"]
        if include_competitors:
            analysis_parts.append("主要競爭對手分析")
        if include_trends:
            analysis_parts.append("市場趨勢分析")

        competitors_json = '"competitors": [{"name": "競品名稱", "strength": "優勢", "weakness": "劣勢"}],' if include_competitors else ""
        trends_json = '"trends": {"current": "當前趨勢", "forecast": "趨勢預測", "seasonality": "季節性因素"},' if include_trends else ""
        analysis_list = '\n'.join([f'{i+1}. {part}' for i, part in enumerate(analysis_parts)])

        prompt = f"""請為以下商品提供市場洞察分析：

商品名稱：{product_name}

請分析以下面向：
{analysis_list}

請用以下 JSON 格式回覆（務必輸出有效的 JSON）：
{{
  "product_name": "{product_name}",
  "market_position": {{
    "target_audience": "目標客群描述",
    "price_range": "價格區間建議",
    "positioning": "市場定位建議"
  }},
  {competitors_json}
  {trends_json}
  "recommendations": ["銷售建議1", "銷售建議2", "銷售建議3"],
  "keywords": ["行銷關鍵字1", "關鍵字2", "關鍵字3"]
}}"""

        return self.generate(prompt, model=model, system_prompt=system_prompt, temperature=0.6, timeout=90)


# 建立全域服務實例
gemini_service = GeminiService()


if __name__ == "__main__":
    # 測試程式碼
    logging.basicConfig(level=logging.INFO)

    service = GeminiService()

    # 測試連線
    print("測試 Gemini 連線...")
    if service.check_connection():
        print(f"連線成功！")

        # 測試文案生成
        print("\n測試文案生成...")
        result = service.generate_sales_copy(
            "玻尿酸保濕面膜",
            trend_keywords=["換季保養", "敏感肌"],
            style="吸睛"
        )
        if result.success:
            print(f"生成結果:\n{result.content}")
            print(f"\n耗時: {result.total_duration:.2f} 秒")
            print(f"Token 用量: 輸入 {result.input_tokens}, 輸出 {result.output_tokens}")
            print(f"費用: ${result.total_cost:.6f} USD")
        else:
            print(f"生成失敗: {result.error}")
    else:
        print("連線失敗（請確認 GEMINI_API_KEY 環境變數）")
