from __future__ import annotations

import hashlib
import json
from datetime import UTC, date, datetime
from decimal import Decimal
from pathlib import Path

from sqlalchemy import inspect, select, text

from app.core.agent_enums import (
    AgentAssetContentType,
    AgentAssetDomain,
    AgentAssetStatus,
    AgentAssetType,
    AgentName,
    AgentPermissionLevel,
    AgentReviewStatus,
    AgentRunSource,
    AgentRunStatus,
    AgentToolType,
)
from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetVersion
from app.models.agent_run import AgentRun, AgentToolCall, SemanticParseLog
from app.models.audit_log import AuditLog
from app.models.financial_record import (
    AccountsPayableRecord,
    AccountsReceivableRecord,
    ExpenseClaim,
    ExpenseClaimItem,
)
from app.services.agent_asset_rule_library import AgentAssetRuleLibraryManager
from app.services.agent_asset_spreadsheet import (
    AgentAssetSpreadsheetManager,
    COMPANY_COMMUNICATION_EXPENSE_RULE_CODE,
    COMPANY_COMMUNICATION_EXPENSE_RULE_FILENAME,
    COMPANY_TRAVEL_EXPENSE_RULE_CODE,
    COMPANY_TRAVEL_EXPENSE_RULE_FILENAME,
    FINANCE_RULES_LIBRARY,
    RISK_RULES_LIBRARY,
)
from app.services.expense_rule_runtime import (
    build_scene_submission_standard_markdown,
    build_travel_risk_control_standard_markdown,
)
from app.services.agent_foundation_constants import (
    ATTACHMENT_RULE_ASSET_CODE,
    ATTACHMENT_RULE_RUNTIME_CONFIG,
    COMPANY_COMMUNICATION_RULE_SCENARIO_JSON,
    COMPANY_COMMUNICATION_RULE_VERSION,
    COMPANY_TRAVEL_RULE_SCENARIO_JSON,
    COMPANY_TRAVEL_RULE_VERSION,
    DEMO_EXPENSE_CLAIM_SIGNATURES,
    DEMO_PAYABLE_SIGNATURES,
    DEMO_RECEIVABLE_SIGNATURES,
    LEGACY_RULE_CODES,
    PLATFORM_DESTINATION_LOCATION_RULE_FILENAME,
)
from app.core.logging import get_logger

logger = get_logger("app.services.agent_foundation")

class AgentFoundationMarkdownMixin:
    def _attachment_submission_requirement_markdown(

        self,

        *,

        version_note: str,

        include_review_note: bool,

    ) -> str:

        sections = [

            "# 报销附件与单据完整性规则",

            "",

            "## 模板信息",

            "",

            "- 模板键：`attachment_requirement_v1`",

            "- 来源文档：报销制度 / 单据与附件要求",

            "- 审核状态：待审核",

            "",

            "## 目标",

            "",

            "统一约束报销提交时的票据、附件与替代凭证要求，避免缺件、错件和无依据流转。",

            "",

            "## 适用范围",

            "",

            "适用于员工报销提交场景，重点覆盖差旅、住宿、交通、餐费、办公和其他费用的附件校验。",

            "",

            "## 输入字段",

            "",

            "- expense_type",

            "- attachments",

            "- invoice_count",

            "- reason",

            "",

            "## 判断规则",

            "",

            "- 报销提交前至少需要 1 份有效附件。",

            "- 金额类报销原则上应提供合法票据；特殊场景无发票时，必须补充收据与情况说明。",

            "- 差旅交通报销需提供行程单或等效凭证；住宿报销需提供酒店票据或等效住宿凭证。",

            "- 缺少必要附件时直接拦截，并提示补件后重新提交。",

            "",

            "## 输出",

            "",

            "- 风险编码：`invoice_anomaly`",

            "- 默认动作：`block`",

            "- 处理说明：附件或单据不完整时退回补充。",

            "",

            "## 来源依据",

            "",

            "- 报销制度对票据、附件、替代凭证和补件要求的统一约束。",

            "",

            "## 审核约束",

            "",

            "- 当前规则属于真实业务规则，但仍处于待审核状态。",

            "- 上线前需由制度管理员确认收据替代、补件时限和特殊场景豁免口径。",

            f"- 当前版本说明：{version_note}",

            "",

            "## 管理员备注",

            "",

            "需要结合公司正式报销制度，补充各场景附件替代口径与例外审批要求。",

        ]

        if include_review_note:

            sections.extend(["", "```expense-rule", json.dumps(ATTACHMENT_RULE_RUNTIME_CONFIG, ensure_ascii=False, indent=2), "```"])

        return "\n".join(sections)

    def _scene_submission_standard_markdown(self) -> str:

        return self._markdown_content(build_scene_submission_standard_markdown())

    def _travel_risk_control_standard_markdown(self, *, version: str = "v1.1.0") -> str:

        return self._markdown_content(build_travel_risk_control_standard_markdown())

    @staticmethod

    def _markdown_content(content: str) -> str:

        return content

    @staticmethod

    def _json_content(content: dict[str, object]) -> str:

        return json.dumps(content, ensure_ascii=False, sort_keys=True, indent=2)
