from fastapi import APIRouter, HTTPException, Query
from decimal import Decimal
from typing import Dict, Any, List
from app.core.database import get_connection

router = APIRouter(prefix="/trial-balance", tags=["試算表"])

def D(x) -> Decimal:
    return Decimal(str(x or 0))

@router.get("", summary="試算表（全科目）")
def get_trial_balance(
    date_from: str = Query(..., description="YYYY-MM-DD"),
    date_to: str = Query(..., description="YYYY-MM-DD"),
):
    if date_from > date_to:
        raise HTTPException(status_code=400, detail="期間指定が不正です。")

    with get_connection() as conn, conn.cursor() as cur:

        # 全科目取得
        cur.execute("""
            SELECT account_id, account_code, account_name, account_type
              FROM accounts
             WHERE is_active = true
             ORDER BY account_code
        """)
        accounts = cur.fetchall()

        result_accounts: List[Dict[str, Any]] = []

        total_opening = Decimal("0")
        total_debit = Decimal("0")
        total_credit = Decimal("0")
        total_closing = Decimal("0")

        for acc in accounts:
            aid = acc["account_id"]

            # 期首残高
            cur.execute("""
                SELECT COALESCE(SUM(l.debit - l.credit), 0) AS opening
                  FROM journal_lines l
                  JOIN journal_entries j ON j.journal_id = l.journal_id
                 WHERE l.account_id = %s
                   AND j.journal_date < %s
            """, (aid, date_from))
            opening = D(cur.fetchone()["opening"])

            # 当期
            cur.execute("""
                SELECT
                    COALESCE(SUM(l.debit), 0) AS debit,
                    COALESCE(SUM(l.credit), 0) AS credit
                  FROM journal_lines l
                  JOIN journal_entries j ON j.journal_id = l.journal_id
                 WHERE l.account_id = %s
                   AND j.journal_date BETWEEN %s AND %s
            """, (aid, date_from, date_to))
            row = cur.fetchone()
            debit = D(row["debit"])
            credit = D(row["credit"])

            closing = opening + debit - credit

            total_opening += opening
            total_debit += debit
            total_credit += credit
            total_closing += closing

            result_accounts.append({
                "account_id": aid,
                "account_code": acc["account_code"],
                "account_name": acc["account_name"],
                "account_type": acc["account_type"],
                "opening_balance": str(opening),
                "debit": str(debit),
                "credit": str(credit),
                "closing_balance": str(closing),
            })

    return {
        "period": {
            "from": date_from,
            "to": date_to
        },
        "totals": {
            "opening_balance": str(total_opening),
            "debit": str(total_debit),
            "credit": str(total_credit),
            "closing_balance": str(total_closing)
        },
        "accounts": result_accounts
    }
