from typing import Dict, List, Optional
from fastapi.param_functions import Query
from pydantic.main import BaseModel
from pydantic.types import Json
from src.apps.tilled.common.enums import TilledRefundReasons
from src.apps.base.utils import regexp
from src.apps._lib.schemas.common import AddressSchema
from src.core.utility.enums import (
    PaymentCurrencies,
    PaymentMethodTypes,
    TransactionCategories,
    TransactionStatusTypes,
    TransactionSourceTypes,
)
from pydantic import Field
from src.apps._lib.schemas.base import BaseSchema
from .transaction_common import TransactionSchema


class TransactionCreateRequestSchema(BaseSchema):
    txn_amount: float = Field(description="Transaction amount value")
    txn_type: PaymentMethodTypes = Field(description="Transaction type")
    currency: PaymentCurrencies = Field(description="Payment currency to be used")
    txn_status: Optional[TransactionStatusTypes] = Field(
        description="Transaction status"
    )
    reference_id: Optional[str] = Field(description="Third party reference id")
    platform_fee_amount: Optional[int] = Field(
        default=0.0, description="Third party gas fees"
    )
    payment_method_id: Optional[str] = Field(
        description="payment Method id of the transaction"
    )
    txn_metadata: Optional[Dict] = Field(
        description="Optional key value pair for storing extra data in transaction. The same will be returned in invoices of this transaction."
    )
    billing_name: Optional[str] = Field(
        description="Optional name used for billing purpose"
    )
    billing_address: Optional[AddressSchema] = Field(
        description="Address used for billing purpose"
    )
    category: Optional[TransactionCategories] = Field(
        description="Transaction category"
    )
    txn_source: Optional[TransactionSourceTypes] = Field(description="Transaction type")


class TransactionUpdateRequestSchema(TransactionSchema):
    pass


class TransactionListFilterSchema(BaseModel):
    search: Optional[str] = Query(
        default=None, description="Search by amount, customer, etc"
    )
    # status: Optional[TransactionStatusTypes] = Query(
    #     default=None, description="Status of transaction"
    # )
    category: str = Query(
        default=None,
        description="Category of the transactions. Choose one of these values: 'charge', 'refund', 'payout', 'dispute'",
    )
    # amount_from: float = Query(
    #     default=None, description="Put the Minimum amount of your need to search"
    # )
    # amount_to: float = Query(
    #     default=None, description="Put Maximum amount of your need to search between"
    # )
    amount_range: Optional[str] = Query(default=None)
    customer_name: Optional[str] = Query(default=None)
    customer_ids: Optional[str] = Query(default=None)
    txn_id: Optional[str] = Query(default=None)
    txn_literal: Optional[str] = Query(default=None)
    txn_type: Optional[str] = Query(default=None)
    zip_code: Optional[str] = Query(default=None)
    pm_details: Optional[str] = Query(default=None)
    invoice_id: Optional[str] = Query(default=None)
    payment_request_id: Optional[str] = Query(default=None)


class TransactionRefundCreateSchema(BaseModel):
    amount: Optional[float] = Field(
        gt=0,
        description="A positive floating point number indicating the Refund amount. Cannot be more than the transaction amount itself. Default is the transaction amount itself.",
    )
    reason: Optional[TilledRefundReasons] = Field(description="Reason for the refund")
    detail: Optional[str] = Field(description="Reason detail for the refund")


class BulkTransactionReceiptSendSchema(BaseModel):
    transaction_ids: List[str] = Field(
        description="txn_ids of the transactions for which the receipts are to be sent"
    )


class GenerateFile(BaseModel):
    file_type: Optional[str] = Query(default=None)
