"""Google Gemini AI Client for Financial Analysis"""
import os
from typing import Optional
from tenacity import retry, stop_after_attempt, wait_fixed

import google.generativeai as genai
from dotenv import load_dotenv

from .data_models import FinancialReport


load_dotenv()


class GeminiClient:
    """Gemini AI Client for generating financial insights"""

    def __init__(self, api_key: str = None, model_name: str = None):
        self.api_key = api_key or os.getenv("GOOGLE_API_KEY")
        self.model_name = model_name or os.getenv("GEMINI_MODEL", "gemini-2.0-flash")

        if not self.api_key:
            raise ValueError("GOOGLE_API_KEY not found. Set it in .env file.")

        genai.configure(api_key=self.api_key)
        self.model = genai.GenerativeModel(self.model_name)

    @retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
    def generate_content(self, prompt: str) -> str:
        """Generate content using Gemini API"""
        response = self.model.generate_content(prompt)
        return response.text.strip()

    def generate_financial_summary(self, report: FinancialReport) -> str:
        """Generate AI summary of financial report"""
        # Build context from report data
        kpi_summary = self._build_kpi_context(report)
        pl_summary = self._build_pl_context(report)

        prompt = f"""あなたは経験豊富な財務アナリストです。以下の財務データを分析し、経営者向けの簡潔なサマリを日本語で作成してください。

## 会社情報
- 会社名: {report.company_name}
- 会計年度: {report.fiscal_year}
- 対象期間: {report.period}
- 対象月: {report.target_month}

## KPI実績
{kpi_summary}

## 損益計算書サマリ
{pl_summary}

## 要求事項
1. 3〜5個の箇条書きで主要なポイントを要約
2. 良い点と改善点をバランスよく記載
3. 具体的な数値を含める
4. 経営判断に役立つ洞察を提供
5. 100〜200文字程度で簡潔に

## 出力形式
HTMLの<ul><li>タグ形式で出力してください。"""

        return self.generate_content(prompt)

    def generate_variance_analysis(self, report: FinancialReport) -> str:
        """Generate AI analysis of budget vs actual variances"""
        variance_data = self._build_variance_context(report)

        prompt = f"""あなたは財務アナリストです。以下の予算と実績の差異データを分析してください。

## 差異データ
{variance_data}

## 分析要求
1. 最も大きな差異がある項目を特定
2. 差異の原因を推測
3. 改善のための提案を含める
4. 日本語で3〜4つの箇条書きで回答

## 出力形式
HTMLの<ul><li>タグ形式で出力してください。"""

        return self.generate_content(prompt)

    def generate_financial_highlights(self, report: FinancialReport) -> dict:
        """Generate financial highlight scores and analysis"""
        kpi_data = self._build_kpi_context(report)

        prompt = f"""あなたは財務アナリストです。以下の財務データを6つの観点で評価してください。

## 財務データ
{kpi_data}

## 評価項目（各5点満点）
1. 売上持続性（売上高増加率）
2. 収益性（営業利益率）
3. 生産性（労働生産性）
4. 健全性（財務健全性）
5. 効率性（資本効率）
6. 安全性（自己資本比率）

## 出力形式
以下のJSON形式で出力してください：
{{
  "total_score": 数値,
  "grade": "A/B/C/D/E",
  "scores": {{
    "売上持続性": {{"score": 数値, "comment": "コメント"}},
    "収益性": {{"score": 数値, "comment": "コメント"}},
    "生産性": {{"score": 数値, "comment": "コメント"}},
    "健全性": {{"score": 数値, "comment": "コメント"}},
    "効率性": {{"score": 数値, "comment": "コメント"}},
    "安全性": {{"score": 数値, "comment": "コメント"}}
  }},
  "overall_comment": "総合コメント"
}}"""

        response = self.generate_content(prompt)

        # Parse JSON response
        import json
        try:
            # Extract JSON from response
            json_start = response.find('{')
            json_end = response.rfind('}') + 1
            if json_start >= 0 and json_end > json_start:
                return json.loads(response[json_start:json_end])
        except json.JSONDecodeError:
            pass

        # Return default if parsing fails
        return {
            "total_score": 21,
            "grade": "B",
            "scores": {
                "売上持続性": {"score": 3, "comment": "データ不足"},
                "収益性": {"score": 4, "comment": "良好"},
                "生産性": {"score": 4, "comment": "良好"},
                "健全性": {"score": 4, "comment": "良好"},
                "効率性": {"score": 3, "comment": "改善余地あり"},
                "安全性": {"score": 3, "comment": "普通"},
            },
            "overall_comment": "全体的に良好な財務状況です。"
        }

    def _build_kpi_context(self, report: FinancialReport) -> str:
        """Build KPI context string for prompts"""
        lines = []
        for kpi in report.annual_kpis:
            target_str = f" (目標: {kpi.target_value:,.0f})" if kpi.target_value else ""
            lines.append(f"- {kpi.title}: {kpi.formatted_value}{target_str}")
        return "\n".join(lines) if lines else "KPIデータなし"

    def _build_pl_context(self, report: FinancialReport) -> str:
        """Build P/L context string for prompts"""
        lines = []
        key_items = ["売上高", "売上原価", "売上総", "営業", "経常", "純利益"]

        for item in report.pl_items:
            if any(key in item.name for key in key_items) and item.level == 0:
                budget = f"{item.total_budget:,.0f}" if item.total_budget else "-"
                actual = f"{item.total_actual:,.0f}"
                variance = item.total_variance
                var_str = f"+{variance:,.0f}" if variance >= 0 else f"{variance:,.0f}"
                lines.append(f"- {item.name}: 実績 {actual}円 (予算比 {var_str}円)")

        return "\n".join(lines) if lines else "P/Lデータなし"

    def _build_variance_context(self, report: FinancialReport) -> str:
        """Build variance context string for prompts"""
        lines = []

        for item in report.pl_items[:15]:  # Top 15 items
            if item.total_budget and item.total_budget != 0:
                variance = item.total_variance
                rate = (variance / abs(item.total_budget)) * 100
                if abs(rate) > 10:  # Only significant variances
                    lines.append(
                        f"- {item.name}: 予算 {item.total_budget:,.0f}円 → "
                        f"実績 {item.total_actual:,.0f}円 (差異 {rate:+.1f}%)"
                    )

        return "\n".join(lines) if lines else "有意な差異なし"


# Singleton instance
_gemini_client: Optional[GeminiClient] = None


def get_gemini_client() -> GeminiClient:
    """Get or create Gemini client singleton"""
    global _gemini_client
    if _gemini_client is None:
        _gemini_client = GeminiClient()
    return _gemini_client
