package domain

import (
	"encoding/json"
	"time"
)

type User struct {
	ID           string    `json:"id"`
	Email        string    `json:"email"`
	FullName     string    `json:"full_name"`
	Role         string    `json:"role"`
	PasswordHash string    `json:"-"`
	CreatedAt    time.Time `json:"created_at"`
}

type KYCProfile struct {
	ID                     string     `json:"id"`
	UserID                 string     `json:"user_id"`
	LegalName              string     `json:"legal_name"`
	DateOfBirth            string     `json:"date_of_birth"`
	Country                string     `json:"country"`
	AddressLine1           string     `json:"address_line1"`
	City                   string     `json:"city"`
	PostalCode             string     `json:"postal_code"`
	Status                 string     `json:"status"`
	Provider               string     `json:"provider"`
	ExternalVerificationID string     `json:"external_verification_id,omitempty"`
	RejectionReason        string     `json:"rejection_reason,omitempty"`
	SubmittedAt            *time.Time `json:"submitted_at,omitempty"`
	VerifiedAt             *time.Time `json:"verified_at,omitempty"`
	CreatedAt              time.Time  `json:"created_at"`
	UpdatedAt              time.Time  `json:"updated_at"`
}

type KYCDocument struct {
	ID             string    `json:"id"`
	KYCProfileID   string    `json:"kyc_profile_id"`
	DocumentType   string    `json:"document_type"`
	DocumentNumber string    `json:"document_number,omitempty"`
	Country        string    `json:"country"`
	Status         string    `json:"status"`
	CreatedAt      time.Time `json:"created_at"`
}

type AMLScreening struct {
	ID                  string          `json:"id"`
	UserID              string          `json:"user_id"`
	KYCProfileID        string          `json:"kyc_profile_id,omitempty"`
	ScreeningType       string          `json:"screening_type"`
	Provider            string          `json:"provider"`
	Status              string          `json:"status"`
	RiskScore           int             `json:"risk_score"`
	Matched             bool            `json:"matched"`
	MatchDetails        json.RawMessage `json:"match_details"`
	ExternalScreeningID string          `json:"external_screening_id,omitempty"`
	CreatedAt           time.Time       `json:"created_at"`
}

type AMLCase struct {
	ID                       string     `json:"id"`
	UserID                   string     `json:"user_id"`
	AMLScreeningID           string     `json:"aml_screening_id,omitempty"`
	CaseType                 string     `json:"case_type"`
	Status                   string     `json:"status"`
	Severity                 string     `json:"severity"`
	Reason                   string     `json:"reason"`
	ResolutionNote           string     `json:"resolution_note,omitempty"`
	AssignedToAdminUserID    string     `json:"assigned_to_admin_user_id,omitempty"`
	SLADueAt                 *time.Time `json:"sla_due_at,omitempty"`
	EscalatedAt              *time.Time `json:"escalated_at,omitempty"`
	ClosedAt                 *time.Time `json:"closed_at,omitempty"`
	RegulatoryReportRequired bool       `json:"regulatory_report_required"`
	FalsePositive            bool       `json:"false_positive"`
	CreatedAt                time.Time  `json:"created_at"`
	UpdatedAt                time.Time  `json:"updated_at"`
}

type Account struct {
	ID                string        `json:"id"`
	UserID            string        `json:"user_id"`
	WalletID          string        `json:"wallet_id,omitempty"`
	AccountNumber     string        `json:"account_number"`
	IBAN              string        `json:"iban"`
	BIC               string        `json:"bic"`
	BankProvider      string        `json:"bank_provider"`
	ExternalAccountID string        `json:"external_account_id,omitempty"`
	Currency          string        `json:"currency"`
	BalanceCents      int64         `json:"balance_cents"`
	Status            string        `json:"status"`
	RoutingCodes      []RoutingCode `json:"routing_codes,omitempty"`
	CreatedAt         time.Time     `json:"created_at"`
	UpdatedAt         time.Time     `json:"updated_at"`
}

type RoutingCode struct {
	ID        string    `json:"id,omitempty"`
	OwnerType string    `json:"owner_type,omitempty"`
	OwnerID   string    `json:"owner_id,omitempty"`
	CodeType  string    `json:"code_type"`
	Country   string    `json:"country"`
	Network   string    `json:"network"`
	Code      string    `json:"code"`
	Status    string    `json:"status,omitempty"`
	CreatedAt time.Time `json:"created_at,omitempty"`
	UpdatedAt time.Time `json:"updated_at,omitempty"`
}

type SavingsGoal struct {
	ID                 string     `json:"id"`
	UserID             string     `json:"user_id"`
	AccountID          string     `json:"account_id"`
	Name               string     `json:"name"`
	Currency           string     `json:"currency"`
	TargetAmountCents  int64      `json:"target_amount_cents"`
	CurrentAmountCents int64      `json:"current_amount_cents"`
	Status             string     `json:"status"`
	TargetDate         string     `json:"target_date,omitempty"`
	CategoryID         string     `json:"category_id,omitempty"`
	Icon               string     `json:"icon,omitempty"`
	Color              string     `json:"color,omitempty"`
	PocketType         string     `json:"pocket_type,omitempty"`
	Visibility         string     `json:"visibility,omitempty"`
	ProviderName       string     `json:"provider_name,omitempty"`
	ExternalPocketID   string     `json:"external_pocket_id,omitempty"`
	ProviderSyncStatus string     `json:"provider_sync_status,omitempty"`
	ProviderSyncError  string     `json:"provider_sync_error,omitempty"`
	ProviderSyncedAt   *time.Time `json:"provider_synced_at,omitempty"`
	CompletedAt        *time.Time `json:"completed_at,omitempty"`
	ClosedAt           *time.Time `json:"closed_at,omitempty"`
	CreatedAt          time.Time  `json:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at"`
}

type SavingsGoalTransaction struct {
	ID             string    `json:"id"`
	SavingsGoalID  string    `json:"savings_goal_id"`
	UserID         string    `json:"user_id"`
	AccountID      string    `json:"account_id"`
	Type           string    `json:"type"`
	AmountCents    int64     `json:"amount_cents"`
	Currency       string    `json:"currency"`
	Description    string    `json:"description,omitempty"`
	IdempotencyKey string    `json:"idempotency_key,omitempty"`
	CreatedAt      time.Time `json:"created_at"`
}

type LedgerAccount struct {
	ID            string    `json:"id"`
	OwnerUserID   string    `json:"owner_user_id,omitempty"`
	ReferenceType string    `json:"reference_type"`
	ReferenceID   string    `json:"reference_id"`
	Currency      string    `json:"currency"`
	NormalBalance string    `json:"normal_balance"`
	Status        string    `json:"status"`
	CreatedAt     time.Time `json:"created_at"`
	UpdatedAt     time.Time `json:"updated_at"`
}

type LedgerJournalEntry struct {
	ID             string              `json:"id"`
	EventType      string              `json:"event_type"`
	SourceType     string              `json:"source_type"`
	SourceID       string              `json:"source_id"`
	IdempotencyKey string              `json:"idempotency_key,omitempty"`
	Description    string              `json:"description,omitempty"`
	Metadata       json.RawMessage     `json:"metadata"`
	Lines          []LedgerJournalLine `json:"lines,omitempty"`
	CreatedAt      time.Time           `json:"created_at"`
}

type LedgerJournalLine struct {
	ID                         string    `json:"id"`
	JournalEntryID             string    `json:"journal_entry_id"`
	LedgerAccountID            string    `json:"ledger_account_id"`
	LedgerAccountReferenceType string    `json:"ledger_account_reference_type"`
	LedgerAccountReferenceID   string    `json:"ledger_account_reference_id"`
	Direction                  string    `json:"direction"`
	AmountCents                int64     `json:"amount_cents"`
	Currency                   string    `json:"currency"`
	CreatedAt                  time.Time `json:"created_at"`
}

type Currency struct {
	Code      string    `json:"code"`
	Name      string    `json:"name"`
	MinorUnit int       `json:"minor_unit"`
	Enabled   bool      `json:"enabled"`
	CreatedAt time.Time `json:"created_at"`
}

type Wallet struct {
	ID        string          `json:"id"`
	UserID    string          `json:"user_id"`
	Name      string          `json:"name"`
	Status    string          `json:"status"`
	Balances  []WalletBalance `json:"balances,omitempty"`
	CreatedAt time.Time       `json:"created_at"`
	UpdatedAt time.Time       `json:"updated_at"`
}

type WalletBalance struct {
	ID                    string    `json:"id"`
	WalletID              string    `json:"wallet_id"`
	Currency              string    `json:"currency"`
	AvailableBalanceCents int64     `json:"available_balance_cents"`
	ReservedBalanceCents  int64     `json:"reserved_balance_cents"`
	CreatedAt             time.Time `json:"created_at"`
	UpdatedAt             time.Time `json:"updated_at"`
}

type WalletBalanceAdjustment struct {
	ID                        string    `json:"id"`
	AdminUserID               string    `json:"admin_user_id"`
	TargetUserID              string    `json:"target_user_id"`
	WalletID                  string    `json:"wallet_id"`
	WalletBalanceID           string    `json:"wallet_balance_id"`
	AccountID                 string    `json:"account_id"`
	Direction                 string    `json:"direction"`
	AmountCents               int64     `json:"amount_cents"`
	Currency                  string    `json:"currency"`
	Reason                    string    `json:"reason"`
	IdempotencyKey            string    `json:"idempotency_key,omitempty"`
	WalletBalanceBeforeCents  int64     `json:"wallet_balance_before_cents"`
	WalletBalanceAfterCents   int64     `json:"wallet_balance_after_cents"`
	AccountBalanceBeforeCents int64     `json:"account_balance_before_cents"`
	AccountBalanceAfterCents  int64     `json:"account_balance_after_cents"`
	CreatedAt                 time.Time `json:"created_at"`
}

type WalletBalanceAdjustmentRequest struct {
	ID                   string     `json:"id"`
	RequesterAdminUserID string     `json:"requester_admin_user_id"`
	RequesterName        string     `json:"requester_name,omitempty"`
	ReviewerAdminUserID  string     `json:"reviewer_admin_user_id,omitempty"`
	ReviewerName         string     `json:"reviewer_name,omitempty"`
	TargetUserID         string     `json:"target_user_id"`
	TargetUserName       string     `json:"target_user_name,omitempty"`
	WalletID             string     `json:"wallet_id"`
	AccountID            string     `json:"account_id"`
	Direction            string     `json:"direction"`
	AmountCents          int64      `json:"amount_cents"`
	Currency             string     `json:"currency"`
	Reason               string     `json:"reason"`
	Status               string     `json:"status"`
	DecisionNote         string     `json:"decision_note,omitempty"`
	AdjustmentID         string     `json:"adjustment_id,omitempty"`
	IdempotencyKey       string     `json:"-"`
	DecidedAt            *time.Time `json:"decided_at,omitempty"`
	CreatedAt            time.Time  `json:"created_at"`
	UpdatedAt            time.Time  `json:"updated_at"`
}

type CryptoAsset struct {
	ID              string    `json:"id"`
	Symbol          string    `json:"symbol"`
	Name            string    `json:"name"`
	Network         string    `json:"network"`
	AssetType       string    `json:"asset_type"`
	ContractAddress string    `json:"contract_address,omitempty"`
	Decimals        int       `json:"decimals"`
	Enabled         bool      `json:"enabled"`
	CreatedAt       time.Time `json:"created_at"`
}

type CryptoWallet struct {
	ID               string                `json:"id"`
	UserID           string                `json:"user_id"`
	Name             string                `json:"name"`
	CustodyProvider  string                `json:"custody_provider"`
	ExternalWalletID string                `json:"-"`
	Status           string                `json:"status"`
	Balances         []CryptoWalletBalance `json:"balances,omitempty"`
	Addresses        []CryptoAddress       `json:"addresses,omitempty"`
	CreatedAt        time.Time             `json:"created_at"`
	UpdatedAt        time.Time             `json:"updated_at"`
}

type CryptoWalletBalance struct {
	ID                       string    `json:"id"`
	CryptoWalletID           string    `json:"crypto_wallet_id"`
	CryptoAssetID            string    `json:"crypto_asset_id"`
	Symbol                   string    `json:"symbol"`
	Network                  string    `json:"network"`
	AvailableAmountBaseUnits string    `json:"available_amount_base_units"`
	ReservedAmountBaseUnits  string    `json:"reserved_amount_base_units"`
	CreatedAt                time.Time `json:"created_at"`
	UpdatedAt                time.Time `json:"updated_at"`
}

type CryptoAddress struct {
	ID             string    `json:"id"`
	CryptoWalletID string    `json:"crypto_wallet_id"`
	CryptoAssetID  string    `json:"crypto_asset_id"`
	Symbol         string    `json:"symbol"`
	Network        string    `json:"network"`
	Address        string    `json:"address"`
	AddressTag     string    `json:"address_tag,omitempty"`
	Status         string    `json:"status"`
	CreatedAt      time.Time `json:"created_at"`
}

type Transfer struct {
	ID                       string        `json:"id"`
	UserID                   string        `json:"user_id"`
	FromAccountID            string        `json:"from_account_id"`
	ToAccountID              string        `json:"to_account_id,omitempty"`
	BeneficiaryID            string        `json:"beneficiary_id,omitempty"`
	BeneficiaryName          string        `json:"beneficiary_name,omitempty"`
	BeneficiaryIBAN          string        `json:"beneficiary_iban,omitempty"`
	BeneficiaryBIC           string        `json:"beneficiary_bic,omitempty"`
	BeneficiaryRoutingCodes  []RoutingCode `json:"beneficiary_routing_codes,omitempty"`
	PaymentReference         string        `json:"payment_reference,omitempty"`
	TransferType             string        `json:"transfer_type"`
	AmountCents              int64         `json:"amount_cents"`
	Currency                 string        `json:"currency"`
	Status                   string        `json:"status"`
	Description              string        `json:"description,omitempty"`
	IdempotencyKey           string        `json:"idempotency_key,omitempty"`
	SettlementAttempts       int           `json:"settlement_attempts,omitempty"`
	SettlementProvider       string        `json:"settlement_provider,omitempty"`
	SettlementReference      string        `json:"settlement_reference,omitempty"`
	SettlementError          string        `json:"settlement_error,omitempty"`
	SettlementNextAttemptAt  *time.Time    `json:"settlement_next_attempt_at,omitempty"`
	SettledAt                *time.Time    `json:"settled_at,omitempty"`
	PaymentReasonCode        string        `json:"payment_reason_code,omitempty"`
	PaymentReasonCategory    string        `json:"payment_reason_category,omitempty"`
	PaymentReasonDescription string        `json:"payment_reason_description,omitempty"`
	ManualReviewRequired     bool          `json:"manual_review_required"`
	CreatedAt                time.Time     `json:"created_at"`
}

type Beneficiary struct {
	ID           string        `json:"id"`
	UserID       string        `json:"user_id"`
	Name         string        `json:"name"`
	IBAN         string        `json:"iban"`
	BIC          string        `json:"bic,omitempty"`
	Currency     string        `json:"currency"`
	Status       string        `json:"status"`
	RoutingCodes []RoutingCode `json:"routing_codes,omitempty"`
	CreatedAt    time.Time     `json:"created_at"`
	UpdatedAt    time.Time     `json:"updated_at"`
}

type VirtualCard struct {
	ID                 string     `json:"id"`
	UserID             string     `json:"user_id"`
	AccountID          string     `json:"account_id"`
	ExternalCardID     string     `json:"-"`
	Nickname           string     `json:"nickname,omitempty"`
	CardholderName     string     `json:"cardholder_name"`
	Network            string     `json:"network"`
	CardType           string     `json:"card_type"`
	Last4              string     `json:"last4"`
	ExpMonth           int        `json:"exp_month"`
	ExpYear            int        `json:"exp_year"`
	SpendingLimitCents int64      `json:"spending_limit_cents"`
	LimitSyncStatus    string     `json:"limit_sync_status"`
	LimitSyncedAt      *time.Time `json:"limit_synced_at,omitempty"`
	LimitSyncError     string     `json:"limit_sync_error,omitempty"`
	CardToken          string     `json:"card_token,omitempty"`
	TokenizationStatus string     `json:"tokenization_status,omitempty"`
	TokenKeyReference  string     `json:"token_key_reference,omitempty"`
	PCIScopeClass      string     `json:"pci_scope_classification,omitempty"`
	Status             string     `json:"status"`
	CreatedAt          time.Time  `json:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at"`
}

type CardAuthorization struct {
	ID                      string          `json:"id"`
	VirtualCardID           string          `json:"virtual_card_id"`
	ExternalAuthorizationID string          `json:"external_authorization_id"`
	AmountCents             int64           `json:"amount_cents"`
	Currency                string          `json:"currency"`
	MerchantName            string          `json:"merchant_name,omitempty"`
	MerchantCategoryCode    string          `json:"merchant_category_code,omitempty"`
	MerchantCountry         string          `json:"merchant_country,omitempty"`
	Status                  string          `json:"status"`
	DeclineReason           string          `json:"decline_reason,omitempty"`
	LedgerStatus            string          `json:"ledger_status,omitempty"`
	ExpiresAt               *time.Time      `json:"expires_at,omitempty"`
	ClearedAt               *time.Time      `json:"cleared_at,omitempty"`
	ReversedAt              *time.Time      `json:"reversed_at,omitempty"`
	DisputedAt              *time.Time      `json:"disputed_at,omitempty"`
	RawEvent                json.RawMessage `json:"raw_event"`
	CreatedAt               time.Time       `json:"created_at"`
	UpdatedAt               time.Time       `json:"updated_at"`
}

type CardholderNotification struct {
	ID                  string     `json:"id"`
	UserID              string     `json:"user_id"`
	VirtualCardID       string     `json:"virtual_card_id,omitempty"`
	CardAuthorizationID string     `json:"card_authorization_id,omitempty"`
	CardDisputeID       string     `json:"card_dispute_id,omitempty"`
	Type                string     `json:"type"`
	Channel             string     `json:"channel"`
	Status              string     `json:"status"`
	Title               string     `json:"title"`
	Body                string     `json:"body"`
	SentAt              *time.Time `json:"sent_at,omitempty"`
	ReadAt              *time.Time `json:"read_at,omitempty"`
	CreatedAt           time.Time  `json:"created_at"`
	UpdatedAt           time.Time  `json:"updated_at"`
}

type CardDispute struct {
	ID                             string     `json:"id"`
	UserID                         string     `json:"user_id"`
	VirtualCardID                  string     `json:"virtual_card_id"`
	CardAuthorizationID            string     `json:"card_authorization_id"`
	ReasonCode                     string     `json:"reason_code"`
	AmountCents                    int64      `json:"amount_cents"`
	Currency                       string     `json:"currency"`
	Status                         string     `json:"status"`
	Description                    string     `json:"description,omitempty"`
	ProvisionalCredit              bool       `json:"provisional_credit"`
	ProvisionalCreditLedgerEventID string     `json:"provisional_credit_ledger_event_id,omitempty"`
	DecisionNote                   string     `json:"decision_note,omitempty"`
	DecidedByAdminUserID           string     `json:"decided_by_admin_user_id,omitempty"`
	DecidedAt                      *time.Time `json:"decided_at,omitempty"`
	CreatedAt                      time.Time  `json:"created_at"`
	UpdatedAt                      time.Time  `json:"updated_at"`
}

type AuditEvent struct {
	ID          string          `json:"id"`
	ActorUserID string          `json:"actor_user_id,omitempty"`
	EventType   string          `json:"event_type"`
	TargetType  string          `json:"target_type"`
	TargetID    string          `json:"target_id"`
	Metadata    json.RawMessage `json:"metadata"`
	RemoteIP    string          `json:"remote_ip,omitempty"`
	UserAgent   string          `json:"user_agent,omitempty"`
	CreatedAt   time.Time       `json:"created_at"`
}
