from fastapi import APIRouter, HTTPException, Query
from decimal import Decimal
from app.core.database import get_connection

router = APIRouter(
    prefix="/general-ledger",
    tags=["元帳"]
)


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


@router.get("", summary="元帳取得（期首残高対応）")
def get_general_ledger(
    account_id: int = Query(..., description="科目ID"),
    fiscal_year: int = Query(..., description="会計年度（例：2025）"),
    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_code, account_name
              FROM accounts
             WHERE account_id = %s
               AND is_active = true
        """, (account_id,))
        acc = cur.fetchone()

        if not acc:
            raise HTTPException(status_code=400, detail="指定された科目は存在しません。")

        # ----------------------------
        # 期首残高（opening_balances）
        # ----------------------------
        cur.execute("""
            SELECT
                COALESCE(opening_debit, 0) - COALESCE(opening_credit, 0) AS opening
              FROM opening_balances
             WHERE fiscal_year = %s
               AND account_id = %s
        """, (fiscal_year, account_id))

        row = cur.fetchone()
        opening_balance = D(row["opening"]) if row else D(0)

        # ----------------------------
        # 期間内仕訳取得
        # ----------------------------
        cur.execute("""
            SELECT
                j.journal_date,
                j.description,
                l.debit,
                l.credit
              FROM journal_entries j
              JOIN journal_lines l
                ON l.journal_id = j.journal_id
              LEFT JOIN journal_entries child
                ON child.parent_entry_id = j.journal_id
             WHERE l.account_id = %s
               AND j.journal_date BETWEEN %s AND %s
               -- 逆仕訳を除外
               AND j.description NOT LIKE '[逆仕訳]%'
               -- 子仕訳（修正後仕訳）を持つ修正前の仕訳を除外
               AND child.journal_id IS NULL
             ORDER BY j.journal_date, l.line_id
        """, (account_id, date_from, date_to))

        rows = cur.fetchall()

        # ----------------------------
        # 累計残高計算
        # ----------------------------
        balance = opening_balance
        lines = []

        for r in rows:
            debit = D(r["debit"])
            credit = D(r["credit"])
            balance += debit - credit

            lines.append({
                "journal_date": r["journal_date"],
                "description": r["description"],
                "debit": str(debit),
                "credit": str(credit),
                "balance": str(balance),
            })

    return {
        "account": {
            "account_id": account_id,
            "account_code": acc["account_code"],
            "account_name": acc["account_name"],
        },
        "fiscal_year": fiscal_year,
        "period": {
            "from": date_from,
            "to": date_to
        },
        "opening_balance": str(opening_balance),
        "lines": lines,
        "closing_balance": str(balance),
    }
