"""
ERP Agent Specialized Tools

Tools specific to Enterprise Resource Planning:
- Purchase orders
- Suppliers/Vendors
- Accounting/Finance
- General ledger
"""
from typing import Any, Dict
from app.tools.base import ReadOnlyTool, WriteTool, ToolParameter, ParameterType, ToolResult
from app.tools.registry import register_tool


@register_tool
class GetPurchaseOrdersTool(ReadOnlyTool):
    """Get purchase orders"""

    name = "get_purchase_orders"
    description = "Get list of purchase orders with status and details"
    category = "erp"
    agent_types = ["erp", "procurement", "accounting"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: draft, pending, approved, received, cancelled",
            required=False
        ),
        ToolParameter(
            name="supplier_id",
            type=ParameterType.STRING,
            description="Filter by supplier ID",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Filter orders from date",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="Filter orders to date",
            required=False
        ),
        ToolParameter(
            name="min_amount",
            type=ParameterType.NUMBER,
            description="Minimum order amount",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_purchase_orders(**params)
            return ToolResult.success_result(data, "Purchase orders retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get purchase orders: {str(e)}")


@register_tool
class GetPurchaseOrderDetailsTool(ReadOnlyTool):
    """Get detailed purchase order info"""

    name = "get_purchase_order_details"
    description = "Get comprehensive purchase order information with line items"
    category = "erp"
    agent_types = ["erp", "procurement", "accounting"]

    parameters = [
        ToolParameter(
            name="order_id",
            type=ParameterType.STRING,
            description="Purchase order ID",
            required=True
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_purchase_order_details(**params)
            return ToolResult.success_result(data, "Purchase order details retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get order details: {str(e)}")


@register_tool
class CreatePurchaseOrderTool(WriteTool):
    """Create a purchase order"""

    name = "create_purchase_order"
    description = "Create a new purchase order"
    category = "erp"
    agent_types = ["erp", "procurement"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="supplier_id",
            type=ParameterType.STRING,
            description="Supplier ID",
            required=True
        ),
        ToolParameter(
            name="items",
            type=ParameterType.ARRAY,
            description="Line items [{product_id, quantity, unit_price}]",
            required=True
        ),
        ToolParameter(
            name="delivery_date",
            type=ParameterType.STRING,
            description="Expected delivery date",
            required=False
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Order notes",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.create_purchase_order(**params)
            return ToolResult.success_result(data, "Purchase order created")
        except Exception as e:
            return ToolResult.error_result(f"Failed to create purchase order: {str(e)}")


@register_tool
class GetSuppliersTool(ReadOnlyTool):
    """Get suppliers/vendors"""

    name = "get_suppliers"
    description = "Get list of suppliers/vendors"
    category = "erp"
    agent_types = ["erp", "procurement"]

    parameters = [
        ToolParameter(
            name="search",
            type=ParameterType.STRING,
            description="Search by name, code, or contact",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: active, inactive, blocked",
            required=False
        ),
        ToolParameter(
            name="category",
            type=ParameterType.STRING,
            description="Filter by supplier category",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_suppliers(**params)
            return ToolResult.success_result(data, "Suppliers retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get suppliers: {str(e)}")


@register_tool
class GetSupplierDetailsTool(ReadOnlyTool):
    """Get detailed supplier information"""

    name = "get_supplier_details"
    description = "Get comprehensive supplier profile with purchase history"
    category = "erp"
    agent_types = ["erp", "procurement"]

    parameters = [
        ToolParameter(
            name="supplier_id",
            type=ParameterType.STRING,
            description="Supplier ID",
            required=True
        ),
        ToolParameter(
            name="include_orders",
            type=ParameterType.BOOLEAN,
            description="Include recent purchase orders",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_supplier_details(**params)
            return ToolResult.success_result(data, "Supplier details retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get supplier details: {str(e)}")


@register_tool
class GetAccountsPayableTool(ReadOnlyTool):
    """Get accounts payable"""

    name = "get_accounts_payable"
    description = "Get outstanding payables and bills"
    category = "erp"
    agent_types = ["erp", "accounting", "finance"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: pending, due, overdue, paid",
            required=False
        ),
        ToolParameter(
            name="supplier_id",
            type=ParameterType.STRING,
            description="Filter by supplier ID",
            required=False
        ),
        ToolParameter(
            name="due_date_from",
            type=ParameterType.STRING,
            description="Filter by due date from",
            required=False
        ),
        ToolParameter(
            name="due_date_to",
            type=ParameterType.STRING,
            description="Filter by due date to",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_accounts_payable(**params)
            return ToolResult.success_result(data, "Accounts payable retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get accounts payable: {str(e)}")


@register_tool
class GetAccountsReceivableTool(ReadOnlyTool):
    """Get accounts receivable"""

    name = "get_accounts_receivable"
    description = "Get outstanding receivables and invoices"
    category = "erp"
    agent_types = ["erp", "accounting", "finance"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: pending, due, overdue, paid",
            required=False
        ),
        ToolParameter(
            name="customer_id",
            type=ParameterType.STRING,
            description="Filter by customer ID",
            required=False
        ),
        ToolParameter(
            name="due_date_from",
            type=ParameterType.STRING,
            description="Filter by due date from",
            required=False
        ),
        ToolParameter(
            name="due_date_to",
            type=ParameterType.STRING,
            description="Filter by due date to",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_accounts_receivable(**params)
            return ToolResult.success_result(data, "Accounts receivable retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get accounts receivable: {str(e)}")


@register_tool
class GetFinancialSummaryTool(ReadOnlyTool):
    """Get financial summary"""

    name = "get_financial_summary"
    description = "Get financial overview with key metrics (revenue, expenses, profit)"
    category = "erp"
    agent_types = ["erp", "accounting", "finance"]

    parameters = [
        ToolParameter(
            name="period",
            type=ParameterType.STRING,
            description="Period: today, this_week, this_month, this_quarter, this_year",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Start date for custom range",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="End date for custom range",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_financial_summary(**params)
            return ToolResult.success_result(data, "Financial summary retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get financial summary: {str(e)}")


@register_tool
class GetExpenseReportsTool(ReadOnlyTool):
    """Get expense reports"""

    name = "get_expense_reports"
    description = "Get expense reports and reimbursement requests"
    category = "erp"
    agent_types = ["erp", "accounting", "finance", "hr"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: draft, submitted, approved, rejected, reimbursed",
            required=False
        ),
        ToolParameter(
            name="employee_id",
            type=ParameterType.STRING,
            description="Filter by employee ID",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Filter by date from",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="Filter by date to",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_expense_reports(**params)
            return ToolResult.success_result(data, "Expense reports retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get expense reports: {str(e)}")
