from fastapi import APIRouter, HTTPException
from app.core.database import get_connection
from pydantic import BaseModel
from typing import List, Optional
from decimal import Decimal
from datetime import date

router = APIRouter(prefix="/journal-entries", tags=["仕訳"])

# journal_lines に line_description カラムが存在するかキャッシュ
_line_description_column_exists: Optional[bool] = None

def _check_line_description_column() -> bool:
    """journal_lines テーブルに line_description カラムが存在するか確認（キャッシュあり）"""
    global _line_description_column_exists
    if _line_description_column_exists is None:
        try:
            with get_connection() as conn:
                with conn.cursor() as cur:
                    cur.execute("""
                        SELECT 1 FROM information_schema.columns
                        WHERE table_name = 'journal_lines'
                          AND column_name = 'line_description'
                    """)
                    _line_description_column_exists = cur.fetchone() is not None
        except Exception:
            _line_description_column_exists = False
    return _line_description_column_exists


class JournalLine(BaseModel):
    account_id: int
    debit: Decimal = Decimal("0")
    credit: Decimal = Decimal("0")
    tax_rate: Optional[int] = None  # 10 or 8 or None
    tax_direction: Optional[str] = None  # "paid" or "received" or None
    line_description: Optional[str] = None  # 行摘要（任意）


class JournalEntryRequest(BaseModel):
    entry_date: date
    description: str
    lines: List[JournalLine]
    tax_paid_account_id: Optional[int] = None  # 仮払消費税等 勘定
    tax_received_account_id: Optional[int] = None  # 仮受消費税等 勘定
    rounding_mode: str = "round"  # "round", "floor", or "ceil"
    original_entry_id: Optional[int] = None  # 修正元の仕訳ID（新版本追踪システム用）
    parent_entry_id: Optional[int] = None  # 互換性のため残す（非推奨）

class JournalEntryUpdateRequest(BaseModel):
    description: str
    lines: List[JournalLine]
    updated_reason: str


class JournalEntryDeleteRequest(BaseModel):
    deleted_reason: str


@router.get("", summary="仕訳一覧取得")
def get_journal_entries(
    from_date: date = None,
    to_date: date = None,
    keyword: str = None,
    account_id: int = None,
    account_side: str = None,  # "debit" or "credit"
    include_history: bool = False
):
    """
    仕訳一覧を検索して取得
    
    - include_history=true: すべての版本を表示（修正歴含む）
    - include_history=false (デフォルト): 最新版本のみを表示
    """
    with get_connection() as conn:
        with conn.cursor() as cur:
            # 首先检查字段是否存在
            cur.execute("""
                SELECT column_name FROM information_schema.columns 
                WHERE table_name = 'journal_entries' 
                AND column_name IN ('is_latest', 'revision_count', 'original_entry_id')
            """)
            existing_fields = {row['column_name'] for row in cur.fetchall()}
            
            # 根据字段是否存在构建不同的查询
            if 'revision_count' in existing_fields and 'is_latest' in existing_fields:
                # 使用新字段的完整查询
                if include_history:
                    sql = """
                        SELECT 
                            je.journal_entry_id,
                            je.entry_date,
                            je.description,
                            je.fiscal_year,
                            je.revision_count,
                            je.is_latest,
                            je.original_entry_id,
                            COALESCE(SUM(jl.debit), 0) as debit_total,
                            COALESCE(SUM(jl.credit), 0) as credit_total,
                            STRING_AGG(DISTINCT CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END, ', ' ORDER BY CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END) as tax_rates
                        FROM journal_entries je
                        LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
                        WHERE je.is_deleted = false
                    """
                else:
                    sql = """
                        SELECT 
                            je.journal_entry_id,
                            je.entry_date,
                            je.description,
                            je.fiscal_year,
                            je.revision_count,
                            je.is_latest,
                            je.original_entry_id,
                            COALESCE(SUM(jl.debit), 0) as debit_total,
                            COALESCE(SUM(jl.credit), 0) as credit_total,
                            STRING_AGG(DISTINCT CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END, ', ' ORDER BY CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END) as tax_rates
                        FROM journal_entries je
                        LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
                        WHERE je.is_deleted = false
                        AND je.is_latest = true
                    """
                params = []
            else:
                # 使用不含新字段的查询（向后兼容）
                sql = """
                    SELECT 
                        je.journal_entry_id,
                        je.entry_date,
                        je.description,
                        je.fiscal_year,
                        1 as revision_count,
                        true as is_latest,
                        NULL::INTEGER as original_entry_id,
                        COALESCE(SUM(jl.debit), 0) as debit_total,
                        COALESCE(SUM(jl.credit), 0) as credit_total,
                        STRING_AGG(DISTINCT CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END, ', ' ORDER BY CASE WHEN jl.tax_rate IS NOT NULL THEN jl.tax_rate::text END) as tax_rates
                    FROM journal_entries je
                    LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
                    WHERE je.is_deleted = false
                """
                params = []
            
            if from_date:
                sql += " AND je.entry_date >= %s"
                params.append(from_date)
            
            if to_date:
                sql += " AND je.entry_date <= %s"
                params.append(to_date)
            
            if keyword:
                sql += " AND je.description LIKE %s"
                params.append(f"%{keyword}%")
            
            # 科目と方向で絞込（SQ副查询で指定の科目・方向を持つ仕訳のみ）
            if account_id and account_side:
                # 科目+方向の組み合わせで絞込
                if account_side == "debit":
                    sql += """ AND je.journal_entry_id IN (
                        SELECT DISTINCT journal_entry_id 
                        FROM journal_lines 
                        WHERE account_id = %s AND debit > 0
                    )"""
                elif account_side == "credit":
                    sql += """ AND je.journal_entry_id IN (
                        SELECT DISTINCT journal_entry_id 
                        FROM journal_lines 
                        WHERE account_id = %s AND credit > 0
                    )"""
                params.append(account_id)
            elif account_id:
                # 方向指定がない場合は科目のみで絞込
                sql += """ AND je.journal_entry_id IN (
                    SELECT DISTINCT journal_entry_id 
                    FROM journal_lines 
                    WHERE account_id = %s
                )"""
                params.append(account_id)
            
            sql += """
                GROUP BY je.journal_entry_id, je.entry_date, je.description, je.fiscal_year """
            
            # 只有当字段存在时才添加到 GROUP BY
            if 'revision_count' in existing_fields:
                sql += ", je.revision_count"
            if 'is_latest' in existing_fields:
                sql += ", je.is_latest"
            if 'original_entry_id' in existing_fields:
                sql += ", je.original_entry_id"
            
            sql += """
                ORDER BY je.entry_date DESC, je.journal_entry_id DESC
            """
            
            cur.execute(sql, params)
            rows = cur.fetchall()
            
            return [dict(row) for row in rows]


@router.get("/{journal_id}", summary="仕訳詳細取得")
def get_journal_entry(journal_id: int):
    """
    指定された仕訳の詳細を取得
    """
    with get_connection() as conn:
        with conn.cursor() as cur:
            # ヘッダー取得
            cur.execute("""
                SELECT 
                    journal_entry_id,
                    entry_date,
                    description,
                    fiscal_year,
                    revision_count,
                    is_latest,
                    original_entry_id,
                    is_deleted
                FROM journal_entries
                WHERE journal_entry_id = %s
            """, (journal_id,))
            
            header = cur.fetchone()
            if not header:
                raise HTTPException(status_code=404, detail="仕訳が存在しません")
            
            # 明細取得
            has_line_desc = _check_line_description_column()
            line_desc_col = ", jl.line_description" if has_line_desc else ""
            cur.execute(f"""
                SELECT 
                    jl.journal_line_id,
                    jl.account_id,
                    a.account_code,
                    a.account_name,
                    jl.debit,
                    jl.credit,
                    jl.tax_rate,
                    jl.tax_direction
                    {line_desc_col}
                FROM journal_lines jl
                JOIN accounts a ON jl.account_id = a.account_id
                WHERE jl.journal_entry_id = %s
                ORDER BY jl.journal_line_id
            """, (journal_id,))
            
            lines = cur.fetchall()
            
            return {
                **dict(header),
                "lines": [dict(line) for line in lines]
            }


@router.get("/{journal_id}/revision-history", summary="修正歴取得")
def get_revision_history(journal_id: int):
    """
    指定された仕訳の修正歴史を取得（すべてのバージョン）
    """
    with get_connection() as conn:
        with conn.cursor() as cur:
            # 最初に、指定されたIDが実際の元の交易か、修正版かを確認
            cur.execute("""
                SELECT original_entry_id FROM journal_entries WHERE journal_entry_id = %s
            """, (journal_id,))
            
            row = cur.fetchone()
            if not row:
                raise HTTPException(status_code=404, detail="仕訳が存在しません")
            
            # 元の交易IDを取得
            original_id = row["original_entry_id"] if row["original_entry_id"] else journal_id
            
            # その交易とすべての修正版を取得
            cur.execute("""
                SELECT 
                    journal_entry_id,
                    entry_date,
                    description,
                    revision_count,
                    is_latest,
                    created_at,
                    created_by,
                    COALESCE(SUM(jl.debit), 0) as debit_total,
                    COALESCE(SUM(jl.credit), 0) as credit_total
                FROM journal_entries je
                LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
                WHERE je.journal_entry_id = %s 
                   OR (je.original_entry_id = %s)
                GROUP BY je.journal_entry_id, je.entry_date, je.description, je.revision_count, je.is_latest, je.created_at, je.created_by
                ORDER BY je.revision_count ASC
            """, (journal_id, original_id))
            
            versions = cur.fetchall()
            
            return {
                "original_entry_id": original_id,
                "total_versions": len(versions),
                "versions": [dict(v) for v in versions]
            }


@router.post("/{journal_id}/reverse", summary="逆仕訳作成")
def create_reverse_entry(journal_id: int):
    """
    指定された仕訳の逆仕訳を作成
    """
    with get_connection() as conn:
        with conn.cursor() as cur:
            # 元仕訳取得
            cur.execute("""
                SELECT entry_date, description, fiscal_year
                FROM journal_entries
                WHERE journal_entry_id = %s AND is_deleted = false
            """, (journal_id,))
            
            header = cur.fetchone()
            if not header:
                raise HTTPException(status_code=404, detail="仕訳が存在しません")
            
            # 元仕訳の明細取得
            cur.execute("""
                SELECT account_id, debit, credit
                FROM journal_lines
                WHERE journal_entry_id = %s
            """, (journal_id,))
            
            lines = cur.fetchall()
            
            # 逆仕訳ヘッダー作成
            cur.execute("""
                INSERT INTO journal_entries (
                    entry_date,
                    description,
                    fiscal_year,
                    version,
                    is_deleted,
                    created_by,
                    parent_entry_id
                )
                VALUES (%s, %s, %s, 1, false, %s, %s)
                RETURNING journal_entry_id
            """, (
                header["entry_date"],
                f"[逆仕訳] {header['description']}",
                header["fiscal_year"],
                "system",
                journal_id  # 逆仕訳の元となる仕訳ID
            ))
            
            new_entry_id = cur.fetchone()["journal_entry_id"]
            
            # 逆仕訳明細作成（借方と貸方を入れ替え）
            for line in lines:
                cur.execute("""
                    INSERT INTO journal_lines (
                        journal_entry_id,
                        account_id,
                        debit,
                        credit
                    )
                    VALUES (%s, %s, %s, %s)
                """, (
                    new_entry_id,
                    line["account_id"],
                    line["credit"],  # 借方と貸方を入れ替え
                    line["debit"]
                ))
            
            conn.commit()
            
            return {
                "status": "ok",
                "reversed_journal_entry_id": new_entry_id,
                "original_journal_entry_id": journal_id
            }


@router.post("", summary="仕訳登録")
def create_journal_entry(req: JournalEntryRequest):

    from app.utils.month_lock import is_month_locked
    from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN, ROUND_UP

    if is_month_locked(req.entry_date):
        raise HTTPException(
            status_code=400,
            detail="该月份已锁定，不能新增仕訳"
        )

    if not req.lines:
        raise HTTPException(status_code=400, detail="仕訳明細不能为空")
    
    # 互換性処理：古い parent_entry_id が提供された場合、original_entry_id として処理
    original_entry_id = req.original_entry_id or req.parent_entry_id

    # 税額計算と税行生成
    all_lines = []
    tax_aggregation = {}  # {"paid": Decimal, "received": Decimal}
    
    # 端数処理モード設定
    rounding_map = {
        "round": ROUND_HALF_UP,
        "floor": ROUND_DOWN,
        "ceil": ROUND_UP
    }
    rounding = rounding_map.get(req.rounding_mode, ROUND_HALF_UP)
    
    for line in req.lines:
        all_lines.append(line)
        
        # 税対象行の場合、税額を計算
        if line.tax_rate and line.tax_direction:
            amount = line.debit if line.debit > 0 else line.credit
            rate = Decimal(str(line.tax_rate)) / Decimal("100")  # 10% -> 0.10
            
            # 入力額は税抜額として、税額 = 税抜額 × 税率
            raw_tax = amount * rate
            tax_amount = raw_tax.quantize(Decimal("1"), rounding=rounding)
            
            # 税方向ごとに集計
            if line.tax_direction not in tax_aggregation:
                tax_aggregation[line.tax_direction] = Decimal("0")
            tax_aggregation[line.tax_direction] += tax_amount
    
    # 集計した税額で税行を追加
    if "paid" in tax_aggregation and tax_aggregation["paid"] > 0:
        if not req.tax_paid_account_id:
            raise HTTPException(status_code=400, detail="仮払消費税等 勘定を選択してください")
        all_lines.append(JournalLine(
            account_id=req.tax_paid_account_id,
            debit=tax_aggregation["paid"],
            credit=Decimal("0")
        ))
    
    if "received" in tax_aggregation and tax_aggregation["received"] > 0:
        if not req.tax_received_account_id:
            raise HTTPException(status_code=400, detail="仮受消費税等 勘定を選択してください")
        all_lines.append(JournalLine(
            account_id=req.tax_received_account_id,
            debit=Decimal("0"),
            credit=tax_aggregation["received"]
        ))
    
    # 借貸平衡校験
    total_debit = sum(l.debit for l in all_lines)
    total_credit = sum(l.credit for l in all_lines)
    if total_debit != total_credit:
        raise HTTPException(status_code=400, detail="借方和贷方不平衡")

    fiscal_year = req.entry_date.year

    with get_connection() as conn:
        # 检查版本追踪字段是否存在
        with conn.cursor() as check_cur:
            check_cur.execute("""
                SELECT column_name FROM information_schema.columns 
                WHERE table_name = 'journal_entries' 
                AND column_name IN ('is_latest', 'revision_count', 'original_entry_id')
            """)
            existing_fields = {row['column_name'] for row in check_cur.fetchall()}
        
        # 如果版本追踪字段存在，使用新系统；否则使用旧系统
        if len(existing_fields) == 3:  # 3个字段都存在
            # 新系统：使用版本追踪 - 内联实现
            with conn.cursor() as cur:
                # ① 如果是修正交易，獲取最新版本的 revision_count
                revision_count = 1
                if original_entry_id:
                    cur.execute("""
                        SELECT revision_count FROM journal_entries
                        WHERE (journal_entry_id = %s OR original_entry_id = %s)
                        AND is_latest = true
                        ORDER BY created_at DESC
                        LIMIT 1
                    """, (original_entry_id, original_entry_id))
                    
                    row = cur.fetchone()
                    if row:
                        revision_count = row['revision_count'] + 1
                    else:
                        revision_count = 2
                
                # ② 如果是修正，標記舊版本
                if original_entry_id:
                    cur.execute("""
                        UPDATE journal_entries 
                        SET is_latest = false 
                        WHERE (journal_entry_id = %s OR original_entry_id = %s)
                        AND is_latest = true
                    """, (original_entry_id, original_entry_id))
                
                # ③ 創建新版本
                cur.execute("""
                    INSERT INTO journal_entries (
                        entry_date,
                        description,
                        fiscal_year,
                        is_latest,
                        revision_count,
                        original_entry_id,
                        is_deleted,
                        created_by
                    )
                    VALUES (%s, %s, %s, true, %s, %s, false, %s)
                    RETURNING journal_entry_id
                """, (
                    req.entry_date,
                    req.description,
                    fiscal_year,
                    revision_count,
                    original_entry_id if original_entry_id else None,
                    "system"
                ))
                
                entry_id = cur.fetchone()["journal_entry_id"]
                
                # ④ 插入交易明細
                has_line_desc = _check_line_description_column()
                for line in all_lines:
                    # 轉換 tax_direction
                    tax_dir_db = None
                    if line.tax_direction:
                        if line.tax_direction == 'paid':
                            tax_dir_db = 'INPUT'
                        elif line.tax_direction == 'received':
                            tax_dir_db = 'OUTPUT'
                        else:
                            tax_dir_db = line.tax_direction.upper()
                    
                    if has_line_desc:
                        cur.execute("""
                            INSERT INTO journal_lines (
                                journal_entry_id,
                                account_id,
                                debit,
                                credit,
                                tax_rate,
                                tax_direction,
                                line_description
                            )
                            VALUES (%s, %s, %s, %s, %s, %s, %s)
                        """, (
                            entry_id,
                            line.account_id,
                            line.debit,
                            line.credit,
                            line.tax_rate,
                            tax_dir_db,
                            line.line_description or None
                        ))
                    else:
                        cur.execute("""
                            INSERT INTO journal_lines (
                                journal_entry_id,
                                account_id,
                                debit,
                                credit,
                                tax_rate,
                                tax_direction
                            )
                            VALUES (%s, %s, %s, %s, %s, %s)
                        """, (
                            entry_id,
                            line.account_id,
                            line.debit,
                            line.credit,
                            line.tax_rate,
                            tax_dir_db
                        ))
                
                conn.commit()
            
            return {
                "status": "ok",
                "journal_entry_id": entry_id,
                "revision_created": original_entry_id is not None
            }
        else:
            # 旧系统：没有版本追踪，直接创建仕訳
            with conn.cursor() as cur:
                cur.execute("""
                    INSERT INTO journal_entries (
                        entry_date, description, fiscal_year, is_deleted, created_by
                    ) VALUES (%s, %s, %s, false, %s)
                    RETURNING journal_entry_id
                """, (req.entry_date, req.description, fiscal_year, "system"))
                
                entry_id = cur.fetchone()["journal_entry_id"]
                
                # 插入交易明細
                has_line_desc = _check_line_description_column()
                for line in all_lines:
                    # 轉換 tax_direction
                    tax_dir_db = None
                    if line.tax_direction:
                        if line.tax_direction == 'paid':
                            tax_dir_db = 'INPUT'
                        elif line.tax_direction == 'received':
                            tax_dir_db = 'OUTPUT'
                        else:
                            tax_dir_db = line.tax_direction.upper()
                    
                    if has_line_desc:
                        cur.execute("""
                            INSERT INTO journal_lines (
                                journal_entry_id, account_id, debit, credit,
                                tax_rate, tax_direction, line_description
                            ) VALUES (%s, %s, %s, %s, %s, %s, %s)
                        """, (
                            entry_id,
                            line.account_id,
                            line.debit,
                            line.credit,
                            line.tax_rate,
                            tax_dir_db,
                            line.line_description or None
                        ))
                    else:
                        cur.execute("""
                            INSERT INTO journal_lines (
                                journal_entry_id, account_id, debit, credit,
                                tax_rate, tax_direction
                            ) VALUES (%s, %s, %s, %s, %s, %s)
                        """, (
                            entry_id,
                            line.account_id,
                            line.debit,
                            line.credit,
                            line.tax_rate,
                            tax_dir_db
                        ))
                
                conn.commit()
            
            return {
                "status": "ok",
                "journal_entry_id": entry_id,
                "revision_created": False,
                "warning": "版本追踪字段不存在，使用降级模式"
            }


@router.put("/{journal_id}")
def update_journal_entry(journal_id: int, req: JournalEntryUpdateRequest):
    from app.utils.month_lock import is_month_locked

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

            # ① 取得现有仕訳
            cur.execute("""
                SELECT journal_date, is_deleted, version
                  FROM journal_entries
                 WHERE journal_id = %s
            """, (journal_id,))
            row = cur.fetchone()

            if not row:
                raise HTTPException(status_code=404, detail="仕訳が存在しません")

            if row["is_deleted"]:
                raise HTTPException(status_code=400, detail="削除済み仕訳は更新できません")

            journal_date = row["journal_date"]

            # 借贷平衡校验（update）
            total_debit = sum(l.debit for l in req.lines)
            total_credit = sum(l.credit for l in req.lines)

            if total_debit != total_credit:
                raise HTTPException(status_code=400, detail="借方和贷方不平衡")


            # ② 月次锁定检查
            if is_month_locked(journal_date):
                raise HTTPException(status_code=400, detail="该月份已锁定，不能修改仕訳")

            # ③ 更新 header
            cur.execute("""
                UPDATE journal_entries
                   SET description = %s,
                       version = version + 1,
                       updated_at = CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Tokyo',
                       updated_reason = %s
                 WHERE journal_id = %s
            """, (
                req.description,
                req.updated_reason,
                journal_id
            ))

            # ④ 删除原有明细（物理删除，OK）
            cur.execute("""
                DELETE FROM journal_lines
                 WHERE journal_id = %s
            """, (journal_id,))

            # ⑤ 插入新明细
            for line in req.lines:
                cur.execute("""
                    INSERT INTO journal_lines (
                        journal_id,
                        account_id,
                        debit,
                        credit
                    ) VALUES (%s, %s, %s, %s)
                """, (
                    journal_id,
                    line.account_id,
                    line.debit,
                    line.credit
                ))

        conn.commit()

    return {
        "status": "ok",
        "journal_id": journal_id,
        "message": "仕訳を更新しました"
    }



@router.delete("/{journal_id}", summary="仕訳削除（ソフト削除）")
def delete_journal_entry(journal_id: int, req: JournalEntryDeleteRequest):
    """
    仕訳をソフト削除し、is_latest フラグを自動更新
    
    ポイント：
    - original_entry_id を持つ版本チェーン全体は影響を受けない
    - 削除されたのが最新版の場合、前の版本を新しい is_latest にする
    - 軟削除（is_deleted=true）なので完全な履歴は保持される
    """
    with get_connection() as conn:
        with conn.cursor() as cur:
            # ① 削除対象の仕訳情報を取得
            cur.execute("""
                SELECT 
                    journal_entry_id,
                    original_entry_id,
                    is_latest,
                    revision_count
                FROM journal_entries
                WHERE journal_entry_id = %s
                  AND is_deleted = false
            """, (journal_id,))
            
            row = cur.fetchone()
            if not row:
                raise HTTPException(
                    status_code=404,
                    detail="仕訳が存在しないか、既に削除されています"
                )
            
            original_entry_id = row["original_entry_id"]
            is_latest = row["is_latest"]
            
            # ② ソフト削除を実行
            cur.execute("""
                UPDATE journal_entries
                   SET is_deleted = true,
                       updated_at = CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Tokyo'
                 WHERE journal_entry_id = %s
            """, (journal_id,))
            
            # ③ 削除されたのが最新版の場合のみ、新しい最新版を設定
            if is_latest:
                # 同じ original_entry_id を持つ未削除版の中で、最新の revision_count を探す
                cur.execute("""
                    SELECT journal_entry_id
                    FROM journal_entries
                    WHERE (original_entry_id = %s OR journal_entry_id = %s)
                      AND is_deleted = false
                      AND journal_entry_id != %s
                    ORDER BY revision_count DESC
                    LIMIT 1
                """, (original_entry_id or journal_id, original_entry_id or journal_id, journal_id))
                
                new_latest = cur.fetchone()
                if new_latest:
                    cur.execute("""
                        UPDATE journal_entries
                        SET is_latest = true
                        WHERE journal_entry_id = %s
                    """, (new_latest["journal_entry_id"],))

        conn.commit()

    return {
        "status": "deleted",
        "journal_entry_id": journal_id,
        "message": "仕訳を削除しました（完全な履歴は保持されます）"
    }
