from pydantic import BaseModel, Field, HttpUrl, model_validator
from typing import Optional, List, Union

class BasicInfo(BaseModel):
    first_name: Optional[str] = Field(default=None, description="First name")
    middle_name: Optional[str] = Field(default=None, description="Middle name (optional)")
    last_name: Optional[str] = Field(default=None, description="Last name")


class RealEState(BasicInfo):
    name: Optional[str] = Field(default=None, description="First name")
    share: Optional[str] = Field(default=None, description="Middle name (optional)")
    value: Optional[str] = Field(default=None, description="Last name")


class RetirementDocumentData(BasicInfo):
    balance: Optional[str] = Field(default=None, description="balance")
    description: Optional[str] = Field(default=None, description="description")
    account_type: Optional[str] = Field(default=None, description="account_type")


class CreditorDocumentData(BasicInfo):
    address: Optional[str] = Field(default=None, description="address")
    lien_nature: Optional[str] = Field(default=None, description="lien_nature")
    claim_amount: Optional[str] = Field(default=None, description="claim_amount")
    has_codebtor: Optional[str] = Field(default=None, description="has_codebtor")
    creditor_name: Optional[str] = Field(default=None, description="creditor_name")
    date_incurred: Optional[str] = Field(default=None, description="date_incurred")
    account_number: Optional[str] = Field(default=None, description="account_number")
    collateral_value: Optional[str] = Field(default=None, description="collateral_value")
    unsecured_portion: Optional[str] = Field(default=None, description="unsecured_portion")
    property_description: Optional[str] = Field(default=None, description="property_description")
    #claim_basis: Optional[str] = Field(default=None, description="claim_basis description")


class PriorityUnsecuredClaimDocumentData(BasicInfo):
    
    address: Optional[str] = Field(
        default=None,
        description="Full address listed in the creditor or claim document"
    )
    claim_basis: Optional[str] = Field(
        default=None,
        description="Reason or basis for the claim (e.g., medical bills, credit card debt)"
    )
    creditor_name: Optional[str] = Field(
        default=None,
        description="Name of the creditor or financial institution making the claim"
    )
    date_incurred: Optional[str] = Field(
        default=None,
        description="Date on which the debt or claim was incurred"
    )
    account_number: Optional[str] = Field(
        default=None,
        description="Account number or reference ID associated with the claim"
    )


class InsuranceData(BasicInfo):
    
    value: Optional[float] = Field(
        default=None,
        description="Monetary value of the insurance, savings, or policy amount"
    )
    description: Optional[str] = Field(
        default=None,
        description="Description of the insurance document (e.g., 401k retirement statement)"
    )
    policy_type: Optional[str] = Field(
        default=None,
        description="Type of insurance or financial policy (e.g., Saving, Life Insurance, Health)"
    )


class ExecutoryContractData(BasicInfo):
    description: Optional[str] = Field(
        default=None,
        description="Description of contract"
    )
    other_party_name: Optional[str] = Field(
        default=None,
        description="Third party name"
    )


class ThirdPartyClaimData(BasicInfo):
    claim_type: Optional[str] = Field(
        default=None,
        description="Claim type"
    )

    claim_index: Optional[str] = Field(
        default=None,
        description="Claim index"
    )

    description: Optional[str] = Field(
        default=None,
        description="description about contract"
    )

    estimated_value: Optional[str] = Field(
        default=None,
        description="value of assets"
    )

class EmploymentData(BasicInfo):
    employer_name: Optional[str] = Field(default=None, description="Name")
    years: Optional[str] = Field(default=None, description="Year")
    address: Optional[str] = Field(default=None, description="Address")
    designation: Optional[str] = Field(default=None, description="Designation")


class AddressData(BaseModel):
    first_name: Optional[str] = Field(default=None, description="First name")
    middle_name: Optional[str] = Field(default=None, description="Middle name (optional)")
    last_name: Optional[str] = Field(default=None, description="Last name")
    city: Optional[str] = Field(default=None, description="City name")
    state: Optional[str] = Field(default=None, description="State name")
    county: Optional[str] = Field(default=None, description="County name")
    zip_code: Optional[str] = Field(default=None, description="ZIP code")
    street_name: Optional[str] = Field(default=None, description="Street name")
    house_number: Optional[str] = Field(default=None, description="House number")

    ssn_full: Optional[str] = Field(default=None, description="Full SSN")
    from_date: Optional[str] = Field(default=None, description="From date")
    to_date: Optional[str] = Field(default=None, description="To date")
    full_address: Optional[str] = Field(default=None, description="Full address")
     
    class Config:
        json_schema_extra = {
            "example": {
                "first_name": "John",
                "middle_name": "",
                "last_name": "Doe",
                "city": "Dummy City",
                "state": "Toronto",
                "county": "Canada",
                "zip_code": "90001",
                "street_name": "Street 7",
                "house_number": "134",
                "ssn_full": "409522002",
                "to_date": "09-30-2025",
                "from_date": "10-01-2024",
                "full_address": "Sarah M. Chen, John R. Chen"
            }
        }


class DocumentVerificationRequest(BaseModel):
    """Request payload for the refactored /verify-address endpoint.

    Fields:
    - file_type: Type/category of the document being analyzed (e.g., 'residence_documents').
    - file_url: Direct URL to the document (image/PDF) to analyze.
    - data: Structured data relevant for the file_type. For 'residence_documents', this is personal/address info.
    """
    file_type: str = Field(description="Type of the document, e.g., 'residence_documents'")
    file_url: HttpUrl = Field(description="Publicly accessible URL of the document to analyze")
    data: AddressData = Field(description="Structured data to verify against the document for this file_type")

    class Config:
        json_schema_extra = {
            "example": {
                "file_type": "residence_documents",
                "file_url": "https://example.com/uploads/doc123.png",
                "data": AddressData.Config.json_schema_extra["example"]
            }
        }

class BankStatementData(BaseModel):
    """Structured input for bank statement verification (updated format).

    New required JSON body (for file_type=bank_statement):
    {
        "first_name": "MP",
        "middle_name": "",
        "last_name": "Convergent",
        "bank_name": "Bank of America",
        "account_type": "Saving",
        "balance": "10000.00"
    }
    """
    first_name: str = Field(description="First name present on statement")
    middle_name: Optional[str] = Field(default="", description="Middle name (optional)")
    last_name: str = Field(description="Last name / surname on statement")
    bank_name: str = Field(description="Expected bank name on statement")
    account_type: str = Field(description="Account type (Saving/Checking/Savings/etc.)")
    balance: str = Field(description="Provided final balance for the latest month")

    class Config:
        json_schema_extra = {
            "example": {
                "first_name": "MP",
                "middle_name": "",
                "last_name": "Convergent",
                "bank_name": "Bank of America",
                "account_type": "Saving",
                "balance": "10000.00"
            }
        }

class VehicleDocumentData(BasicInfo):
    """Structured input for vehicle document verification.

    Expected JSON body (for file_type=vehicle_document):
    {
        "year": "2020",
        "maker": "Honda",
        "model": "Honda Shine",
        "mileage": "60",
        "value": "10000.00",
        "vehicle_no": "WB051BE2494"
    }

    Notes:
    - The system will also extract expiry date from the document and determine if it's expired; you do not need to supply expiry.
    """
    year: Optional[str] = Field(default=None, description="Vehicle year (optional if not applicable)")
    maker: Optional[str] = Field(default=None, description="Vehicle manufacturer/maker")
    model: Optional[str] = Field(default=None, description="Vehicle model name")
    mileage: Optional[str] = Field(default=None, description="Vehicle mileage/odometer reading (optional)")
    #value: Optional[str] = Field(default=None, description="Vehicle value (optional)")
    # Accept incoming JSON key 'vehicle_no' while internally using field name 'number'
    vehicle_number: Optional[str] = Field(default=None, alias="vehicle_no", description="Vehicle registration/plate number")
    current_value: Optional[str] = Field(default=None, description="Vehicle value (optional)")

    class Config:
        json_schema_extra = {
            "example": {
                "year": "2020",
                "maker": "Honda",
                "model": "Honda Shine",
                "mileage": "60",
                "value": "10000.00",
                "vehicle_no": "WB051BE2494"
            }
        }


class BusinessDocumentData(BasicInfo):
    """Structured input for business document verification.

    Expected JSON body (for file_type=business_documents):
    {
        "ein": "B2",
        "type": "Stock Broker",
        "location": "LK",
        "business_name": "Business2"
    }

    Notes:
    - Field name 'type' is accepted from input but internally stored as 'business_type' to avoid ambiguity.
    - All fields are required for a positive overall match.
    """
    ein: str = Field(description="Employer Identification Number or equivalent business identifier")
    business_type: str = Field(alias="type", description="Business type or category (e.g., Stock Broker)")
    location: str = Field(description="Business location (country/state code or city)")
    business_name: str = Field(description="Registered business name")

    class Config:
        populate_by_name = True
        json_schema_extra = {
            "example": {
                "ein": "B2",
                "type": "Stock Broker",
                "location": "LK",
                "business_name": "Business2"
            }
        }


class IncomeData(BasicInfo):
    payer: Optional[str] = Field(default=None, description="Payer")
    years: Optional[str] = Field(default=None, description="Years")
    monthly_avg: Optional[str] = Field(default=None, description="monthly_avg")

class GrossOvertimeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Employment year")
    employer_name: Optional[str] = Field(default=None, description="Employer name")
    monthly_avg: Optional[str] = Field(default=None, description="Monthly average income")

class RentalIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of rental activity")
    property: Optional[str] = Field(default=None, description="Rental property description")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly rental income")

class RoyaltiesIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of royalty income")
    source: Optional[str] = Field(default=None, description="Royalty income source")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly royalties income")

class PensionIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of pension income")
    source: Optional[str] = Field(default=None, description="Pension provider or source")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly pension income")

class FamilySupportIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of family support income")
    source: Optional[str] = Field(default=None, description="Source of family support (alimony, child support)")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly family support income")

class SecurityIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of Social Security income")
    source: Optional[str] = Field(default=None, description="Social Security source")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly Social Security income")

class SocialSecurityActBenefitsData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of Social Security Act benefits")
    source: Optional[str] = Field(default=None, description="Source of benefits")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly benefit amount")

class SocialSecurityActBenefitsData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of Social Security Act benefits")
    source: Optional[str] = Field(default=None, description="Source of benefits")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly benefit amount")

class PublicAssistanceData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of public assistance")
    source: Optional[str] = Field(default=None, description="Program or assistance source")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly assistance income")

class OtherIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of other income")
    source: Optional[str] = Field(default=None, description="Source of other income")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly other income")

class SpouseIncomeData(BasicInfo):
    years: Optional[str] = Field(default=None, description="Year of spouse income")
    source: Optional[str] = Field(default=None, description="Spouse income source")
    monthly_avg: Optional[str] = Field(default=None, description="Average monthly spouse income")

class RentHomeData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class UtilitiesData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class TransportationData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class VehicleInsuranceData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    vehicle_number: Optional[str] = Field(default=None, description="Vehicle number")

class TaxesData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class InstallmentPaymentsData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class AlimonySupportData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class InsuranceData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class RetirementContributionsData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class OtherExpensesData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount")
    description: Optional[str] = Field(default=None, description="Description")

class InsiderPaymentData(BasicInfo):
    details: Optional[str] = Field(default=None, description="Details about the insider payment")

class PaidTransferredPropertyData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount paid or transferred")
    details: Optional[str] = Field(default=None, description="Details about the property transfer")
    recipient: Optional[str] = Field(default=None, description="Recipient name")

class PaidTransferHelpCreditorsData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount paid or transferred")
    details: Optional[str] = Field(default=None, description="Details about helping with creditors")
    recipient: Optional[str] = Field(default=None, description="Recipient name")

class SoldTradedTransferredPropertyData(BasicInfo):
    value: Optional[str] = Field(default=None, description="Value of property sold/traded/transferred")
    details: Optional[str] = Field(default=None, description="Details about the property transaction")
    recipient: Optional[str] = Field(default=None, description="Recipient or buyer name")

class OweMoneyCreditorsData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Amount owed")
    details: Optional[str] = Field(default=None, description="Details about the debt")
    creditor: Optional[str] = Field(default=None, description="Creditor name")

class PropertyTakenCollateralDebtData(BasicInfo):
    details: Optional[str] = Field(default=None, description="Details about collateral")
    creditor: Optional[str] = Field(default=None, description="Creditor name")
    property: Optional[str] = Field(default=None, description="Property description")

class CourtActionData(BasicInfo):
    details: Optional[str] = Field(default=None, description="Case details or number")
    court: Optional[str] = Field(default=None, description="Court name")
    status: Optional[str] = Field(default=None, description="Case status")

class PropertyRepossessedData(BasicInfo):
    creditor: Optional[str] = Field(default=None, description="Creditor name")
    property: Optional[str] = Field(default=None, description="Property description")
    details: Optional[str] = Field(default=None, description="Repossession details or number")

class CreditorsLegalProcessClaimsData(BasicInfo):
    creditor: Optional[str] = Field(default=None, description="Creditor name")
    details: Optional[str] = Field(default=None, description="Legal process details")

class GaveGiftsOver600LastYearData(BasicInfo):
    amount: Optional[str] = Field(default=None, description="Gift amount")
    date: Optional[str] = Field(default=None, description="Date of gift")
    recipient: Optional[str] = Field(default=None, description="Recipient name")

class FinancialAccountsChangedLastYearData(BasicInfo):
    institution: Optional[str] = Field(default=None, description="Financial institution name")
    date: Optional[str] = Field(default=None, description="Date of change")
    details: Optional[str] = Field(default=None, description="Details about the change")

class HousingMortgageData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly mortgage or rent payment amount")
    description: Optional[str] = Field(default=None, description="Description of housing payment")

class PublicTransportationData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly public transportation cost")
    description: Optional[str] = Field(default=None, description="Description of transportation expenses")

class SecuredDebtPaymentsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly secured debt payment amount")
    description: Optional[str] = Field(default=None, description="Description of secured debt payment")

class OtherNecessaryExpensesData(BasicInfo):
    description: Optional[str] = Field(default=None, description="Description of other necessary expenses")

class PriorityClaimsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly priority claims amount")
    description: Optional[str] = Field(default=None, description="Description of priority claims")

class CharitableContributionsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly charitable contribution amount")
    description: Optional[str] = Field(default=None, description="Description of charitable contribution")
    recipient_name: Optional[str] = Field(default=None, description="Name of recipient organization")
    recipient_type: Optional[str] = Field(default=None, description="Type of recipient (e.g., Charity)")
    recipient_address: Optional[str] = Field(default=None, description="Address of recipient organization")
    recipient_frequency: Optional[str] = Field(default=None, description="Frequency of contributions")

class AdditionalSecurityData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly additional food/clothing expenses")
    description: Optional[str] = Field(default=None, description="Description of additional expenses")

class HomeEnergyCostsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly home energy costs beyond standards")
    description: Optional[str] = Field(default=None, description="Description of additional energy costs")

class EducationDependentsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly education expenses for dependents")
    description: Optional[str] = Field(default=None, description="Description of education expenses")
    school: Optional[str] = Field(default=None, description="Name of school or educational institution")

class ElderlyDisabledCareData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly care expenses for elderly/disabled")
    description: Optional[str] = Field(default=None, description="Description of care services")
    care_details: Optional[str] = Field(default=None, description="Detailed description of care provided")

class HealthDisabilityInsuranceData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly health/disability insurance or HSA expenses")
    description: Optional[str] = Field(default=None, description="Description of health insurance premium or HSA expenses")

class TelecommunicationsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly telecommunication service costs")
    description: Optional[str] = Field(default=None, description="Description of telecommunication services")

class HealthcareBeyondStandardsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly healthcare costs beyond standards")
    description: Optional[str] = Field(default=None, description="Description of healthcare expenses (e.g., prescriptions)")

class ChildcareExpensesData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly childcare expenses")
    description: Optional[str] = Field(default=None, description="Description of childcare services")
    child_age: Optional[str] = Field(default=None, description="Age of child receiving care")
    provider_name: Optional[str] = Field(default=None, description="Name of childcare provider")
    provider_address: Optional[str] = Field(default=None, description="Address of childcare provider")

class EducationExpensesData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly education expenses for employment or disabled child")
    description: Optional[str] = Field(default=None, description="Description of education expenses")
    school_provider: Optional[str] = Field(default=None, description="Name of school or education provider")

class CourtOrderedPaymentsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly court-ordered payment amount")
    description: Optional[str] = Field(default=None, description="Description of court-ordered payment (e.g., alimony, child support)")

class LifeInsuranceData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly life insurance premium")
    description: Optional[str] = Field(default=None, description="Description of life insurance policy")

class InvoluntaryDeductionsData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly involuntary deductions amount")
    description: Optional[str] = Field(default=None, description="Description of involuntary deductions (e.g., wage garnishment)")

class TaxesActualData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly tax payment amount (actual, not withheld)")
    description: Optional[str] = Field(default=None, description="Description of tax payments")

class VehicleOwnershipData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly vehicle ownership/lease payment")
    description: Optional[str] = Field(default=None, description="Description of vehicle ownership or lease")

class HealthcareExpensesData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly out-of-pocket healthcare expenses beyond IRS standards")
    description: Optional[str] = Field(default=None, description="Description of healthcare expenses")

class HousingInsuranceData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly housing insurance or operating expenses")
    description: Optional[str] = Field(default=None, description="Description of housing insurance/maintenance")

class VehicleOperationData(BasicInfo):
    monthly_amount: Optional[str] = Field(default=None, description="Monthly vehicle operation expenses")
    description: Optional[str] = Field(default=None, description="Description of vehicle operation expenses")
    numbers_of_vehicles: Optional[str] = Field(default=None, description="Number of vehicles operated")

class SpouseBusinessPLData(BasicInfo):
    spouse_business_ein: Optional[str] = Field(default=None, description="Spouse's business EIN")
    spouse_business_zip: Optional[str] = Field(default=None, description="Spouse's business ZIP code")
    spouse_business_city: Optional[str] = Field(default=None, description="Spouse's business city")
    spouse_business_name: Optional[str] = Field(default=None, description="Spouse's business name")
    spouse_business_type: Optional[str] = Field(default=None, description="Spouse's business type")
    spouse_business_unit: Optional[str] = Field(default=None, description="Spouse's business unit/suite number")
    spouse_business_phone: Optional[str] = Field(default=None, description="Spouse's business phone")
    spouse_business_state: Optional[str] = Field(default=None, description="Spouse's business state")
    spouse_business_address: Optional[str] = Field(default=None, description="Spouse's business street address")

class SelfEmploymentPLData(BasicInfo):
    self_business_ein: Optional[str] = Field(default=None, description="Self-employed business EIN")
    self_business_zip: Optional[str] = Field(default=None, description="Self-employed business ZIP code")
    self_business_city: Optional[str] = Field(default=None, description="Self-employed business city")
    self_business_name: Optional[str] = Field(default=None, description="Self-employed business name")
    self_business_type: Optional[str] = Field(default=None, description="Self-employed business type")
    self_business_unit: Optional[str] = Field(default=None, description="Self-employed business unit/suite number")
    self_business_phone: Optional[str] = Field(default=None, description="Self-employed business phone")
    self_business_state: Optional[str] = Field(default=None, description="Self-employed business state")
    self_business_address: Optional[str] = Field(default=None, description="Self-employed business street address")


class CreditorPaymentData(BasicInfo):
    date: Optional[str] = Field(default=None, description="Payment date (MM/YYYY format)")
    name: Optional[str] = Field(default=None, description="Creditor name")
    address: Optional[str] = Field(default=None, description="Creditor address")
    description: Optional[str] = Field(default=None, description="Payment description")
    owed_amount: Optional[str] = Field(default=None, description="Amount owed")
    paid_amount: Optional[str] = Field(default=None, description="Amount paid")
    creditor_type: Optional[str] = Field(default=None, description="Type of creditor (e.g., Loan repayment)")


class InsiderBenefitData(BasicInfo):
    payment_date: Optional[str] = Field(default=None, description="Benefit date (MM/YYYY format)")
    name: Optional[str] = Field(default=None, description="Insider name")
    address: Optional[str] = Field(default=None, description="Insider address")
    description: Optional[str] = Field(default=None, description="Benefit description")
    owed_amount: Optional[str] = Field(default=None, description="Amount owed")
    paid_amount: Optional[str] = Field(default=None, description="Benefit amount received")


class InsiderPaymentDocumentData(BasicInfo):
    date: Optional[str] = Field(default=None, description="Payment date (MM/YYYY format)")
    name: Optional[str] = Field(default=None, description="Insider name")
    address: Optional[str] = Field(default=None, description="Insider address")
    description: Optional[str] = Field(default=None, description="Payment description")
    owed_amount: Optional[str] = Field(default=None, description="Amount owed")
    paid_amount: Optional[str] = Field(default=None, description="Amount paid")


FILE_TYPE_MAP = {
    "bank_statement": BankStatementData,
    "residence_documents": AddressData,
    "billing_address_document": AddressData,
    "vehicle_documents": VehicleDocumentData,
    "business_documents": BusinessDocumentData,
    "address_documents": AddressData,
    "ssn_documents": AddressData,
    "lease_documents": AddressData,
    "real_estate_documents": RealEState,
    "recreational_vehicle_documents": VehicleDocumentData,
    "equipment_documents": VehicleDocumentData,
    "retirement_documents": RetirementDocumentData,
    "creditor_documents": CreditorDocumentData,
    "priority_unsecured_claim_documents": PriorityUnsecuredClaimDocumentData,
    "insurance_policies": InsuranceData,
    "executory_contract_documents": ExecutoryContractData,
    "third_party_claim_documents": ThirdPartyClaimData,
    "employment_documents": EmploymentData,
    "spouse_employment_documents": EmploymentData,
    "net_income_documents" : IncomeData,
    "gross_overtime_documents": GrossOvertimeData,
    "rental_income_documents": RentalIncomeData,
    "royalties_income_documents": RoyaltiesIncomeData,
    "pension_income_documents": PensionIncomeData,
    "family_support_income_documents": FamilySupportIncomeData,
    "security_income_documents": SecurityIncomeData,
    "social_security_act_benefits_documents": SocialSecurityActBenefitsData,
    "public_assistance_documents": PublicAssistanceData, 
    "other_income_documents": OtherIncomeData, 
    "spouse_income_documents": SpouseIncomeData,
    "rent_home_records": RentHomeData,
    "utilities_records": UtilitiesData,
    "transportation_records": TransportationData,
    "vehicle_insurance_records": VehicleInsuranceData,
    "taxes_records": TaxesData,
    "installment_payments_records": InstallmentPaymentsData,
    "alimony_support_records": AlimonySupportData,
    "insurance_records": InsuranceData,
    "retirement_contributions_records": RetirementContributionsData,
    "other_expenses_records": OtherExpensesData,
    "insider_payment_documents": InsiderPaymentData,
    "paid_transferred_property_documents": PaidTransferredPropertyData,
    "paid_transfer_help_creditors_documents": PaidTransferHelpCreditorsData,
    "sold_traded_transferred_property_documents": SoldTradedTransferredPropertyData,
    "owe_money_to_creditors_documents": OweMoneyCreditorsData,
    "property_taken_as_collateral_debt_documents": PropertyTakenCollateralDebtData,
    "court_action_documents": CourtActionData,
    "property_repossessed_documents": PropertyRepossessedData,
    "creditors_legal_process_claims_documents": CreditorsLegalProcessClaimsData,
    "gave_gifts_over_600_last_year_documents": GaveGiftsOver600LastYearData,
    "financial_accounts_changed_last_year_documents": FinancialAccountsChangedLastYearData,
    "housing_mortgage_records": HousingMortgageData,    
    "public_transportation_records": PublicTransportationData,
    "secured_debt_payments_records": SecuredDebtPaymentsData,
    "other_necessary_expenses_records": OtherNecessaryExpensesData,
    "priority_claims_records": PriorityClaimsData,
    "charitable_contributions_records": CharitableContributionsData,
    "additional_security_records": AdditionalSecurityData,
    "home_energy_costs_records": HomeEnergyCostsData,
    "education_dependents_records": EducationDependentsData,
    "elderly_disabled_care_records": ElderlyDisabledCareData,
    "health_disability_insurance_records": HealthDisabilityInsuranceData,
    "telecommunications_records": TelecommunicationsData,
    "healthcare_beyond_standards_records": HealthcareBeyondStandardsData,
    "childcare_expenses_records": ChildcareExpensesData,
    "education_expenses_records": EducationExpensesData,
    "court_ordered_payments_records": CourtOrderedPaymentsData,
    "life_insurance_records": LifeInsuranceData,
    "involuntary_deductions_records": InvoluntaryDeductionsData,
    "vehicle_ownership_records": VehicleOwnershipData,
    "healthcare_expenses_records": HealthcareExpensesData,
    "housing_insurance_records": HousingInsuranceData,
    "vehicle_operation_records": VehicleOperationData,
    "taxes_actual_records": TaxesActualData,
    "spouse_business_pl_documents": SpouseBusinessPLData,
    "self_employment_pl_documents": SelfEmploymentPLData,
    "creditor_payment_documents": CreditorPaymentData,
    "insider_benefit_documents": InsiderBenefitData,
    "insider_payment_documents": InsiderPaymentDocumentData,
}

class MultiDocumentVerificationRequest(BaseModel):
    """Unified request schema for multi-file document verification.

    Supports:
    - file_type == 'bank_statement' -> data must conform to BankStatementData
    - file_type in ['residence_documents', 'billing_address_document'] -> data must conform to AddressData
    - file_urls: list of one or more public URLs (image or PDF). For backward compatibility caller can also send a single URL.

    Example:
    {
        "file_type": "bank_statement",
        "file_urls": [
            "https://example.com/storage/stmt_may.pdf",
            "https://example.com/storage/stmt_june.pdf"
        ],
        "data": {
            "first_name": "MP",
            "middle_name": "",
            "last_name": "Convergent",
            "bank_name": "Bank of America",
            "account_type": "Saving",
            "balance": "10000.00"
        }
    }
    """
    file_type: str
    file_urls: List[HttpUrl]
    data: dict
    callback_url: Optional[str] = None  # Optional callback URL for async Celery processing

    @model_validator(mode="after")
    def validate_and_cast(self):
        if self.file_type not in FILE_TYPE_MAP:
            raise ValueError(f"Invalid file_type: {self.file_type}")

        Model = FILE_TYPE_MAP[self.file_type]
        self.data = Model(**self.data)
        return self

    @classmethod
    def from_raw(cls, raw: dict):
        """Helper to flexibly parse incoming raw body where file_urls may be a comma-separated string."""
        if isinstance(raw.get("file_urls"), str):
            urls = [u.strip() for u in raw["file_urls"].split(',') if u.strip()]
            raw["file_urls"] = urls
        return cls(**raw)

    class Config:
        json_schema_extra = {
            "example": {
                "file_type": "vehicle_document",
                "file_urls": ["https://example.com/uploads/vehicle_card.jpg"],
                "data": VehicleDocumentData.Config.json_schema_extra["example"]
            }
        }
