"""MCP server exposing EDINET tools to LLMs via FastMCP.

This module defines the MCP (Model Context Protocol) server that allows
AI assistants like Claude to search Japanese companies, retrieve financial
filings, and parse XBRL financial statements through EDINET.

Usage with Claude Desktop (add to ``claude_desktop_config.json``)::

    {
      "mcpServers": {
        "edinet": {
          "command": "uvx",
          "args": ["edinet-mcp", "serve"]
        }
      }
    }
"""

from __future__ import annotations

from typing import Annotated, Any

from fastmcp import FastMCP
from pydantic import Field

from edinet_mcp.client import EdinetClient

mcp = FastMCP(
    name="EDINET",
    instructions=(
        "EDINET MCP server provides tools for accessing Japanese financial "
        "disclosure data. You can search for companies listed on the Tokyo "
        "Stock Exchange, retrieve financial filings (有価証券報告書, 四半期報告書), "
        "and parse XBRL financial statements (BS, PL, CF) into structured data.\n\n"
        "All financial data comes from EDINET, the Electronic Disclosure for "
        "Investors' NETwork operated by Japan's Financial Services Agency (FSA)."
    ),
)

# Lazily initialized client
_client: EdinetClient | None = None


def _get_client() -> EdinetClient:
    global _client
    if _client is None:
        _client = EdinetClient()
    return _client


@mcp.tool()
async def search_companies(
    query: Annotated[
        str,
        Field(description="企業名(日本語 or 英語)、証券コード、またはEDINETコードで検索"),
    ],
) -> list[dict[str, Any]]:
    """Search for Japanese companies registered in EDINET.

    Examples:
    - search_companies("トヨタ") → Toyota Motor Corporation
    - search_companies("7203") → Toyota (by ticker)
    - search_companies("E02144") → Toyota (by EDINET code)
    """
    client = _get_client()
    companies = client.search_companies(query)
    return [c.model_dump() for c in companies[:20]]  # Cap at 20 results


@mcp.tool()
async def get_filings(
    edinet_code: Annotated[
        str,
        Field(description="企業のEDINETコード (例: 'E02144')"),
    ],
    start_date: Annotated[
        str,
        Field(description="検索開始日 (YYYY-MM-DD形式)"),
    ],
    end_date: Annotated[
        str | None,
        Field(description="検索終了日 (YYYY-MM-DD形式、省略時は今日)"),
    ] = None,
    doc_type: Annotated[
        str | None,
        Field(
            description=(
                "書類タイプでフィルタ: 'annual_report' (有価証券報告書), "
                "'quarterly_report' (四半期報告書), または省略で全件"
            )
        ),
    ] = None,
) -> list[dict[str, Any]]:
    """List financial filings for a company within a date range.

    Returns filing metadata including doc_id, filing date, and document type.
    Use the doc_id with get_financial_statements to retrieve actual data.
    """
    client = _get_client()
    filings = client.get_filings(
        start_date=start_date,
        end_date=end_date,
        edinet_code=edinet_code,
        doc_type=doc_type,
    )
    return [f.model_dump(mode="json") for f in filings[:50]]


@mcp.tool()
async def get_financial_statements(
    edinet_code: Annotated[
        str,
        Field(description="企業のEDINETコード (例: 'E02144')"),
    ],
    period: Annotated[
        str | None,
        Field(description="会計年度 (例: '2024')。省略時は最新の報告書を取得"),
    ] = None,
    doc_type: Annotated[
        str,
        Field(description="'annual_report' (有価証券報告書) or 'quarterly_report' (四半期報告書)"),
    ] = "annual_report",
) -> dict[str, Any]:
    """Retrieve and parse financial statements (BS, PL, CF) for a company.

    Returns structured balance sheet, income statement, and cash flow data
    parsed from XBRL filings. Data is extracted from real EDINET disclosures.
    """
    client = _get_client()
    stmt = client.get_financial_statements(
        edinet_code=edinet_code,
        doc_type=doc_type,
        period=period,
    )
    result: dict[str, Any] = {
        "filing": stmt.filing.model_dump(mode="json"),
        "accounting_standard": stmt.accounting_standard.value,
    }
    for name, data in stmt.all_statements.items():
        result[name] = data.to_dicts()
    return result


@mcp.tool()
async def get_company_info(
    edinet_code: Annotated[
        str,
        Field(description="企業のEDINETコード (例: 'E02144')"),
    ],
) -> dict[str, Any]:
    """Get detailed information about a company by EDINET code."""
    client = _get_client()
    company = client.get_company(edinet_code)
    return company.model_dump()
