<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class CoachPlanPurchase extends Model
{
    protected $fillable = [
        'coach_plan_id',
        'client_id',
        'user_id',
        'coach_id',
        'payment_reference',
        'amount',
        'currency',
        'buyer_name',
        'buyer_email',
        'buyer_phone',
        'tier_name',
        'status',
        'payment_method',
        'payment_method_id',
        'paid_at',
        'receipt_uploaded_at',
        'starts_at',
        'ends_at',
        'notes',
        'metadata',
        'expiring_notified_at',
        'expired_notified_at',
        'suspended_at',
        'suspension_reason',
        'is_recurring',
        'recurring_period',
        'next_payment_due',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'paid_at' => 'datetime',
        'receipt_uploaded_at' => 'datetime',
        'starts_at' => 'datetime',
        'ends_at' => 'datetime',
        'metadata' => 'array',
        'expiring_notified_at' => 'datetime',
        'expired_notified_at' => 'datetime',
        'suspended_at' => 'datetime',
        'next_payment_due' => 'datetime',
        'is_recurring' => 'boolean',
    ];

    /**
     * Get the coach plan.
     */
    public function coachPlan(): BelongsTo
    {
        return $this->belongsTo(CoachPlan::class);
    }

    /**
     * Get the client.
     */
    public function client(): BelongsTo
    {
        return $this->belongsTo(Client::class);
    }

    /**
     * Get the user (buyer).
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

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

    /**
     * Get the payment method used.
     */
    public function paymentMethodRecord(): BelongsTo
    {
        return $this->belongsTo(CoachPaymentMethod::class, 'payment_method_id');
    }

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

    /**
     * Check if purchase is active.
     */
    public function isActive(): bool
    {
        return $this->status === 'paid' && $this->ends_at > now();
    }

    /**
     * Check if purchase is expired.
     */
    public function isExpired(): bool
    {
        return $this->status === 'paid' && $this->ends_at <= now();
    }

    /**
     * Get remaining days.
     */
    public function getRemainingDaysAttribute(): int
    {
        if (!$this->ends_at || $this->ends_at <= now()) {
            return 0;
        }

        return (int) now()->diffInDays($this->ends_at);
    }

    /**
     * Mark as paid.
     */
    public function markAsPaid(?string $paymentReference = null): void
    {
        $durationDays = $this->coachPlan->duration_days;

        $updateData = [
            'status' => 'paid',
            'payment_reference' => $paymentReference,
            'paid_at' => now(),
            'starts_at' => now(),
            'ends_at' => now()->addDays($durationDays),
        ];

        // Set next payment due if recurring
        if ($this->is_recurring && $this->recurring_period) {
            $periodDays = match ($this->recurring_period) {
                'semana' => 7,
                'mes' => 30,
                'trimestre' => 90,
                'semestre' => 180,
                'año' => 365,
                default => $durationDays,
            };
            $updateData['next_payment_due'] = now()->addDays($periodDays);
        }

        $this->update($updateData);

        // Increment client count on the plan
        $this->coachPlan->increment('current_clients');

        // Notify admins about the coach plan payment
        $this->notifyAdmins();
    }

    /**
     * Notify admins about the purchase payment.
     */
    protected function notifyAdmins(): void
    {
        // Create a pseudo-invoice for notification purposes
        $admins = User::where('role', 'admin')->get();

        foreach ($admins as $admin) {
            $admin->notify(new \App\Notifications\AdminCoachPlanPurchased($this));
        }
    }

    /**
     * Get the status badge color.
     */
    public function getStatusBadgeAttribute(): string
    {
        return match ($this->status) {
            'pending' => 'yellow',
            'paid' => 'green',
            'cancelled' => 'gray',
            'refunded' => 'red',
            'expired' => 'red',
            'suspended' => 'orange',
            default => 'gray',
        };
    }

    /**
     * Get the status label.
     */
    public function getStatusLabelAttribute(): string
    {
        return match ($this->status) {
            'pending' => 'Pendiente',
            'paid' => 'Pagado',
            'cancelled' => 'Cancelado',
            'refunded' => 'Reembolsado',
            'expired' => 'Expirado',
            'suspended' => 'Suspendido',
            default => ucfirst($this->status),
        };
    }

    /**
     * Suspend the purchase.
     */
    public function suspend(?string $reason = null): void
    {
        $this->update([
            'status' => 'suspended',
            'suspended_at' => now(),
            'suspension_reason' => $reason,
        ]);

        if ($this->user) {
            $this->user->notify(new \App\Notifications\CoachPlanSuspended($this, $reason));
        }
    }

    /**
     * Reactivate a suspended purchase.
     */
    public function reactivate(): void
    {
        $this->update([
            'status' => 'paid',
            'suspended_at' => null,
            'suspension_reason' => null,
        ]);
    }
}
