<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Crypt;

class CoachPaymentMethod extends Model
{
    use HasFactory, SoftDeletes;

    const TYPE_PAYPAL = 'paypal';
    const TYPE_BANK_DOMINICAN = 'bank_dominican';
    const TYPE_BANK_INTERNATIONAL = 'bank_international';
    const TYPE_WESTERN_UNION = 'western_union';

    const TYPES = [
        self::TYPE_PAYPAL,
        self::TYPE_BANK_DOMINICAN,
        self::TYPE_BANK_INTERNATIONAL,
        self::TYPE_WESTERN_UNION,
    ];

    // Dominican banks with logos
    const DOMINICAN_BANKS = [
        'banreservas' => [
            'name' => 'Banreservas',
            'logo' => 'https://www.banreservas.com.do/Style%20Library/banreservas/images/logo-banreservas.svg',
            'color' => '#006847',
        ],
        'popular' => [
            'name' => 'Banco Popular Dominicano',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/popular-dominicano.png',
            'color' => '#002D72',
        ],
        'bhd' => [
            'name' => 'Banco BHD León',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/bhd-leon.png',
            'color' => '#003DA5',
        ],
        'scotiabank' => [
            'name' => 'Scotiabank RD',
            'logo' => 'https://www.scotiabank.com/content/dam/scotiabank/images/logos/2019/scotiabank-logo-red-desktop-200px.png',
            'color' => '#EC111A',
        ],
        'santacruz' => [
            'name' => 'Banco Santa Cruz',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/santa-cruz.png',
            'color' => '#1E3A8A',
        ],
        'progreso' => [
            'name' => 'Banco del Progreso',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/banco-del-progreso.png',
            'color' => '#0056A4',
        ],
        'caribe' => [
            'name' => 'Banco Caribe',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/caribe.png',
            'color' => '#F7941D',
        ],
        'lafise' => [
            'name' => 'Banco LAFISE',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/lafise.png',
            'color' => '#003366',
        ],
        'promerica' => [
            'name' => 'Banco Promerica',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/promerica.png',
            'color' => '#00529B',
        ],
        'banesco' => [
            'name' => 'Banesco',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/banesco.png',
            'color' => '#00416A',
        ],
        'ademi' => [
            'name' => 'Banco ADEMI',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/ademi.png',
            'color' => '#F15A24',
        ],
        'vimenca' => [
            'name' => 'Banco Vimenca',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/vimenca.png',
            'color' => '#0033A0',
        ],
        'empire' => [
            'name' => 'Banco Empire',
            'logo' => null,
            'color' => '#8B0000',
        ],
        'bellbank' => [
            'name' => 'Bellbank',
            'logo' => null,
            'color' => '#1E90FF',
        ],
        'qik' => [
            'name' => 'QIK Banco Digital',
            'logo' => 'https://qik.do/content/dam/qik/icons/qik-logo.svg',
            'color' => '#6B3FA0',
        ],
        'billet' => [
            'name' => 'Billet',
            'logo' => 'https://www.banreservas.com.do/Style%20Library/banreservas/images/logo-banreservas.svg',
            'color' => '#00A651',
        ],
        'mio' => [
            'name' => 'MIO (Banco Popular)',
            'logo' => 'https://www.bfrlatam.com/uploads/site/logos/popular-dominicano.png',
            'color' => '#E30613',
        ],
        'other' => [
            'name' => 'Otro banco',
            'logo' => null,
            'color' => '#6B7280',
        ],
    ];

    // Helper to get bank names for backward compatibility
    public static function getDominicanBankNames(): array
    {
        return array_map(fn($bank) => is_array($bank) ? $bank['name'] : $bank, self::DOMINICAN_BANKS);
    }

    const ACCOUNT_TYPES = [
        'ahorro' => 'Cuenta de Ahorro',
        'corriente' => 'Cuenta Corriente',
    ];

    const DOCUMENT_TYPES = [
        'cedula' => 'Cédula',
        'passport' => 'Pasaporte',
        'rnc' => 'RNC',
    ];

    protected $fillable = [
        'coach_id',
        'type',
        'name',
        'is_active',
        'is_verified',
        'verification_token',
        'verified_at',
        // PayPal
        'paypal_email',
        'paypal_me_link',
        'paypal_client_id',
        'paypal_secret',
        'paypal_sandbox',
        // Dominican Bank
        'bank_name',
        'bank_logo',
        'bank_account_number',
        'bank_account_type',
        'bank_holder_name',
        'bank_holder_document',
        'bank_holder_document_type',
        // International Bank
        'bank_country',
        'bank_swift',
        'bank_iban',
        'bank_currency',
        'bank_routing_number',
        'bank_additional_info',
        // Western Union
        'wu_full_name',
        'wu_country',
        'wu_city',
        'wu_phone',
        'wu_id_type',
        'wu_id_number',
        // Common
        'priority',
        'metadata',
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'is_verified' => 'boolean',
        'paypal_sandbox' => 'boolean',
        'verified_at' => 'datetime',
        'metadata' => 'array',
        'priority' => 'integer',
    ];

    protected $hidden = [
        'paypal_secret',
        'verification_token',
    ];

    /**
     * Boot the model.
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            // Generate verification token
            if (!$model->verification_token) {
                $model->verification_token = bin2hex(random_bytes(32));
            }
        });
    }

    /**
     * Get the coach that owns this payment method.
     */
    public function coach(): BelongsTo
    {
        return $this->belongsTo(User::class, 'coach_id');
    }

    /**
     * Get payment receipts for this method.
     */
    public function receipts(): HasMany
    {
        return $this->hasMany(PaymentReceipt::class, 'payment_method_id');
    }

    /**
     * Encrypt PayPal secret when setting.
     */
    public function setPaypalSecretAttribute($value)
    {
        if ($value) {
            $this->attributes['paypal_secret'] = Crypt::encryptString($value);
        } else {
            $this->attributes['paypal_secret'] = null;
        }
    }

    /**
     * Decrypt PayPal secret when getting.
     */
    public function getPaypalSecretAttribute($value)
    {
        if ($value) {
            try {
                return Crypt::decryptString($value);
            } catch (\Exception $e) {
                return null;
            }
        }
        return null;
    }

    /**
     * Mask bank account number for display.
     */
    public function getMaskedAccountNumberAttribute(): ?string
    {
        if (!$this->bank_account_number) {
            return null;
        }

        $number = $this->bank_account_number;
        $length = strlen($number);

        if ($length <= 4) {
            return $number;
        }

        return str_repeat('*', $length - 4) . substr($number, -4);
    }

    /**
     * Get display name for the payment method.
     */
    public function getDisplayNameAttribute(): string
    {
        if ($this->name) {
            return $this->name;
        }

        switch ($this->type) {
            case self::TYPE_PAYPAL:
                $mode = $this->metadata['paypal_mode'] ?? 'email';
                if ($mode === 'paypalme' && $this->paypal_me_link) {
                    return 'PayPal.Me - paypal.me/' . $this->paypal_me_link;
                }
                if ($mode === 'api') {
                    return 'PayPal API' . ($this->paypal_sandbox ? ' (Sandbox)' : '');
                }
                return 'PayPal' . ($this->paypal_email ? ' - ' . $this->paypal_email : '');

            case self::TYPE_BANK_DOMINICAN:
                $bankData = self::DOMINICAN_BANKS[$this->bank_name] ?? null;
                $bankName = is_array($bankData) ? $bankData['name'] : ($bankData ?? $this->bank_name);
                return $bankName . ($this->masked_account_number ? ' - ' . $this->masked_account_number : '');

            case self::TYPE_BANK_INTERNATIONAL:
                return ($this->bank_name ?: 'Banco Internacional') .
                       ($this->bank_country ? ' (' . $this->bank_country . ')' : '');

            case self::TYPE_WESTERN_UNION:
                return 'Western Union - ' . ($this->wu_full_name ?: 'Sin nombre');

            default:
                return 'Método de pago';
        }
    }

    /**
     * Get type label.
     */
    public function getTypeLabelAttribute(): string
    {
        return match ($this->type) {
            self::TYPE_PAYPAL => 'PayPal',
            self::TYPE_BANK_DOMINICAN => 'Banco Dominicano',
            self::TYPE_BANK_INTERNATIONAL => 'Banco Internacional',
            self::TYPE_WESTERN_UNION => 'Western Union',
            default => 'Otro',
        };
    }

    /**
     * Get icon for the payment method type.
     */
    public function getIconAttribute(): string
    {
        return match ($this->type) {
            self::TYPE_PAYPAL => 'paypal',
            self::TYPE_BANK_DOMINICAN => 'bank',
            self::TYPE_BANK_INTERNATIONAL => 'globe-bank',
            self::TYPE_WESTERN_UNION => 'western-union',
            default => 'credit-card',
        };
    }

    /**
     * Get data to show to customers (hides sensitive info).
     */
    public function getPublicDataAttribute(): array
    {
        $data = [
            'id' => $this->id,
            'type' => $this->type,
            'type_label' => $this->type_label,
            'name' => $this->display_name,
            'icon' => $this->icon,
        ];

        switch ($this->type) {
            case self::TYPE_PAYPAL:
                $paypalMode = $this->metadata['paypal_mode'] ?? 'email';
                $data['paypal_mode'] = $paypalMode;
                $data['paypal_email'] = $this->paypal_email;
                if ($paypalMode === 'paypalme') {
                    $data['paypal_me_link'] = $this->paypal_me_link;
                }
                break;

            case self::TYPE_BANK_DOMINICAN:
                $bankData = self::DOMINICAN_BANKS[$this->bank_name] ?? null;
                $data['bank_name'] = is_array($bankData) ? $bankData['name'] : ($bankData ?? $this->bank_name);
                $data['account_number'] = $this->bank_account_number;
                $data['account_type'] = self::ACCOUNT_TYPES[$this->bank_account_type] ?? $this->bank_account_type;
                $data['holder_name'] = $this->bank_holder_name;
                $data['holder_document'] = $this->bank_holder_document;
                $data['document_type'] = self::DOCUMENT_TYPES[$this->bank_holder_document_type] ?? $this->bank_holder_document_type;
                // Include bank logo (custom upload or default from bank data)
                if ($this->bank_logo) {
                    $data['bank_logo'] = asset('storage/' . $this->bank_logo);
                } elseif (is_array($bankData) && !empty($bankData['logo'])) {
                    $data['bank_logo'] = $bankData['logo'];
                }
                $data['bank_key'] = $this->bank_name;
                $data['bank_color'] = is_array($bankData) ? ($bankData['color'] ?? '#10B981') : '#10B981';
                break;

            case self::TYPE_BANK_INTERNATIONAL:
                $data['bank_name'] = $this->bank_name;
                $data['country'] = $this->bank_country;
                $data['swift'] = $this->bank_swift;
                $data['iban'] = $this->bank_iban;
                $data['currency'] = $this->bank_currency;
                $data['account_number'] = $this->bank_account_number;
                $data['holder_name'] = $this->bank_holder_name;
                $data['routing_number'] = $this->bank_routing_number;
                $data['additional_info'] = $this->bank_additional_info;
                break;

            case self::TYPE_WESTERN_UNION:
                $data['full_name'] = $this->wu_full_name;
                $data['country'] = $this->wu_country;
                $data['city'] = $this->wu_city;
                $data['phone'] = $this->wu_phone;
                break;
        }

        return $data;
    }

    /**
     * Validate Dominican cedula format.
     */
    public static function validateDominicanCedula(string $cedula): bool
    {
        // Remove dashes and spaces
        $cedula = preg_replace('/[^0-9]/', '', $cedula);

        // Must be 11 digits
        if (strlen($cedula) !== 11) {
            return false;
        }

        // Luhn-like validation for Dominican cedula
        $weights = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
        $sum = 0;

        for ($i = 0; $i < 10; $i++) {
            $product = intval($cedula[$i]) * $weights[$i];
            $sum += $product >= 10 ? $product - 9 : $product;
        }

        $checkDigit = (10 - ($sum % 10)) % 10;

        return $checkDigit === intval($cedula[10]);
    }

    /**
     * Format Dominican cedula for display.
     */
    public static function formatDominicanCedula(string $cedula): string
    {
        $cedula = preg_replace('/[^0-9]/', '', $cedula);

        if (strlen($cedula) === 11) {
            return substr($cedula, 0, 3) . '-' . substr($cedula, 3, 7) . '-' . substr($cedula, 10, 1);
        }

        return $cedula;
    }

    /**
     * Validate MTCN (Western Union tracking number).
     */
    public static function validateMTCN(string $mtcn): bool
    {
        $mtcn = preg_replace('/[^0-9]/', '', $mtcn);
        return strlen($mtcn) === 10;
    }

    /**
     * Scope for active methods.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope for verified methods.
     */
    public function scopeVerified($query)
    {
        return $query->where('is_verified', true);
    }

    /**
     * Scope by type.
     */
    public function scopeOfType($query, string $type)
    {
        return $query->where('type', $type);
    }

    /**
     * Scope ordered by priority.
     */
    public function scopeOrdered($query)
    {
        return $query->orderBy('priority', 'asc')->orderBy('created_at', 'desc');
    }
}
