/**
 * Types TypeScript pour le module Banking - COOP-CA AMIFOND
 *
 * Types correspondant aux modèles Django backend pour les opérations bancaires
 */

import { z } from "zod";

// Types pour les statuts d'objets Banking
export type AccountStatus = "active" | "frozen" | "closed";
export type AccountType = "savings" | "checking" | "credit" | "pso" | "loan";
export type TransactionStatus = "pending" | "completed" | "failed" | "cancelled";
export type TransactionType = "deposit" | "withdrawal" | "transfer" | "fee" | "interest" | "adjustment";
export type TransferStatus = "pending" | "processing" | "completed" | "failed" | "cancelled" | "scheduled";

// Interface pour Client utilisé dans Banking (référence légère)
export interface BankingClient {
  id: number;
  client_number: string;
  full_name: string;
  email?: string;
  status: string;
}

// Interface pour les comptes bancaires
export interface Account {
  id: number;
  account_number: string;
  client: BankingClient;
  balance: string; // Decimal as string from Django
  currency: string;
  status: AccountStatus;
  overdraft_limit: string; // Decimal as string
  interest_rate: string; // Decimal as string
  account_type: string;
  opened_date: string; // ISO date string
  closed_date?: string; // ISO date string
  last_activity_date?: string; // ISO date string
  notes?: string;
  created_at: string; // ISO datetime string
  updated_at: string; // ISO datetime string
}

// Interface pour les comptes bancaires utilisée par les composants UI
export interface BankingAccount {
  id: string;
  account_name: string;
  account_number: string;
  balance: number;
  account_type: string;
  status: AccountStatus;
  credit_limit?: number;
  interest_rate?: number;
  last_transaction_date?: string;
  // Client information for UI display
  client_name?: string;
  client_email?: string;
}

// Interface pour les transactions utilisée par les composants UI
export interface BankingTransaction {
  id: string;
  transaction_id: string;
  transaction_date: string; // ISO date string
  transaction_type: TransactionType;
  amount: number;
  currency: string;
  description: string;
  reference?: string;
  status: TransactionStatus;
  account_id: string;
  account_name?: string; // Added for UI display
  account_number?: string; // Added for UI display
  beneficiary_account_id?: string;
  beneficiary_account_name?: string; // Added for UI display
  beneficiary_account_number?: string; // Added for UI display
}

// Interface pour les transactions
export interface Transaction {
  id: number;
  transaction_id: string;
  account: {
    id: number;
    account_number: string;
    client: BankingClient;
  };
  beneficiary_account?: {
    id: number;
    account_number: string;
    client: BankingClient;
  };
  type: TransactionType;
  amount: string; // Decimal as string
  currency: string;
  description: string;
  reference?: string;
  status: TransactionStatus;
  debit_amount?: string; // Decimal as string
  credit_amount?: string; // Decimal as string
  balance_after: string; // Decimal as string
  processed_date?: string; // ISO datetime string
  created_at: string; // ISO datetime string
  updated_at: string; // ISO datetime string
}

// Interface pour les transferts
export interface Transfer {
  id: number;
  transfer_id: string;
  from_account: {
    id: number;
    account_number: string;
    client: BankingClient;
  };
  to_account: {
    id: number;
    account_number: string;
    client: BankingClient;
  };
  amount: string; // Decimal as string
  currency: string;
  description: string;
  reference?: string;
  status: TransferStatus;
  fee_amount: string; // Decimal as string
  scheduled_date?: string; // ISO datetime string
  processed_date?: string; // ISO datetime string
  transaction?: Transaction; // Transaction associée après traitement
  created_at: string; // ISO datetime string
  updated_at: string; // ISO datetime string
}

// Interface pour les détails de solde (balance details)
export interface BalanceDetails {
  account: Account;
  current_balance: string; // Decimal as string
  available_balance: string; // Decimal as string
  pending_debits: string; // Decimal as string
  pending_credits: string; // Decimal as string
  overdraft_available: string; // Decimal as string
  last_updated: string; // ISO datetime string
}

// Types pour les réponses API (liste avec pagination)
export interface PaginatedResponse<T> {
  count: number;
  next?: string;
  previous?: string;
  results: T[];
}

// Types de réponse pour les listes
export type AccountListResponse = PaginatedResponse<Account>;
export type TransactionListResponse = PaginatedResponse<Transaction>;
export type TransferListResponse = PaginatedResponse<Transfer>;

// Types pour les formulaires de création/modification
export interface AccountCreateData {
  client_id: number;
  account_type: string;
  currency?: string;
  overdraft_limit?: string;
  interest_rate?: string;
  notes?: string;
}

// Alias pour compatibilité avec les composants
export type CreateAccountRequest = AccountCreateData;

export interface AccountUpdateData {
  status?: AccountStatus;
  overdraft_limit?: string;
  interest_rate?: string;
  notes?: string;
}

export interface TransactionCreateData {
  account_id: number;
  type: TransactionType;
  amount: string;
  description: string;
  reference?: string;
  beneficiary_account_id?: number;
}

export interface TransferCreateData {
  from_account_id: number;
  to_account_id: number;
  amount: string;
  description: string;
  reference?: string;
  scheduled_date?: string; // ISO datetime string pour transfers programmés
}

// Types pour les opérations spéciales
export interface DepositData {
  account_id: number;
  amount: string;
  description: string;
  reference?: string;
}

export interface WithdrawalData {
  account_id: number;
  amount: string;
  description: string;
  reference?: string;
}

// Types pour les filtres de recherche
export interface AccountFilters {
  client_id?: number;
  status?: AccountStatus;
  account_type?: string;
  currency?: string;
  search?: string; // Recherche par numéro de compte ou nom client
  [key: string]: string | number | undefined;
}

export interface TransactionFilters {
  account_id?: number;
  type?: TransactionType;
  status?: TransactionStatus;
  from_date?: string; // ISO date string
  to_date?: string; // ISO date string
  min_amount?: string;
  max_amount?: string;
  search?: string; // Recherche par référence ou description
  [key: string]: string | number | undefined;
}

export interface TransferFilters {
  from_account_id?: number;
  to_account_id?: number;
  status?: TransferStatus;
  from_date?: string; // ISO date string
  to_date?: string; // ISO date string
  min_amount?: string;
  max_amount?: string;
  search?: string; // Recherche par référence ou description
  [key: string]: string | number | undefined;
}

// Types pour les statistiques Banking
export interface BankingStats {
  total_accounts: number;
  active_accounts: number;
  total_balance: string; // Decimal as string
  total_transactions_today: number;
  total_transfers_pending: number;
  accounts_by_status: Record<AccountStatus, number>;
  transactions_by_type: Record<TransactionType, number>;
  monthly_transaction_volume: string; // Decimal as string
}

// Types pour les rapports
export interface AccountStatement {
  account: Account;
  from_date: string;
  to_date: string;
  opening_balance: string;
  closing_balance: string;
  transactions: Transaction[];
  summary: {
    total_debits: string;
    total_credits: string;
    transaction_count: number;
  };
}

// Schémas Zod pour la validation des formulaires
export const accountCreateSchema = z.object({
  client_id: z.number().positive("L'ID client est requis"),
  account_type: z.string().min(1, "Le type de compte est requis"),
  currency: z.string().optional(),
  overdraft_limit: z.string().optional(),
  interest_rate: z.string().optional(),
  notes: z.string().optional(),
});

export const transferCreateSchema = z
  .object({
    from_account_id: z.number().positive("Le compte source est requis"),
    to_account_id: z.number().positive("Le compte destination est requis"),
    amount: z
      .string()
      .min(1, "Le montant est requis")
      .refine((val) => {
        const num = parseFloat(val);
        return !isNaN(num) && num > 0;
      }, "Le montant doit être un nombre positif"),
    description: z.string().min(1, "La description est requise"),
    reference: z.string().optional(),
    scheduled_date: z.string().optional(),
  })
  .refine((data) => data.from_account_id !== data.to_account_id, {
    message: "Le compte source et destination doivent être différents",
    path: ["to_account_id"],
  });

export const transactionCreateSchema = z.object({
  account_id: z.number().positive("L'ID compte est requis"),
  type: z.enum(["deposit", "withdrawal", "transfer", "fee", "interest", "adjustment"]),
  amount: z
    .string()
    .min(1, "Le montant est requis")
    .refine((val) => {
      const num = parseFloat(val);
      return !isNaN(num) && num > 0;
    }, "Le montant doit être un nombre positif"),
  description: z.string().min(1, "La description est requise"),
  reference: z.string().optional(),
  beneficiary_account_id: z.number().optional(),
});

// Types pour les actions en lot (bulk actions)
export interface BulkAccountAction {
  action: "freeze" | "unfreeze" | "close";
  account_ids: number[];
  reason?: string;
}

export interface BulkTransactionAction {
  action: "cancel" | "reverse";
  transaction_ids: number[];
  reason?: string;
}

// Types pour les erreurs spécifiques au Banking
export interface BankingError {
  code: string;
  message: string;
  details?: Record<string, string | number | boolean>;
}

// Constantes pour les types d'opérations
export const TRANSACTION_TYPES = {
  DEPOSIT: "deposit",
  WITHDRAWAL: "withdrawal",
  TRANSFER: "transfer",
  FEE: "fee",
  INTEREST: "interest",
  ADJUSTMENT: "adjustment",
} as const;

export const ACCOUNT_STATUSES = {
  ACTIVE: "active",
  FROZEN: "frozen",
  CLOSED: "closed",
} as const;

export const TRANSFER_STATUSES = {
  PENDING: "pending",
  PROCESSING: "processing",
  COMPLETED: "completed",
  FAILED: "failed",
  CANCELLED: "cancelled",
  SCHEDULED: "scheduled",
} as const;

// Types dérivés des schémas Zod
export type AccountCreateFormData = z.infer<typeof accountCreateSchema>;
export type TransferCreateFormData = z.infer<typeof transferCreateSchema>;
export type TransactionCreateFormData = z.infer<typeof transactionCreateSchema>;
