<?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;

/**
 * Model: RPartnership (MOU/Agreement)
 * 
 * Tracks formal partnership agreements, MOUs, and contracts.
 * Supports document attachments and renewal tracking.
 * 
 * @property int $id
 * @property int $partner_id
 * @property string $title
 * @property string $agreement_type
 * @property string|null $description
 * @property string|null $objectives
 * @property string|null $scope
 * @property \Carbon\Carbon $start_date
 * @property \Carbon\Carbon|null $end_date
 * @property bool $auto_renew
 * @property int|null $renewal_period_months
 * @property string|null $document_path
 * @property string|null $document_name
 * @property float|null $value
 * @property string $currency
 * @property string|null $resources_committed
 * @property string $status
 * @property \Carbon\Carbon|null $signed_date
 * @property \Carbon\Carbon|null $review_date
 * @property int|null $manager_id
 * @property bool $expiry_notification_sent
 */
class RPartnership extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'r_partnerships';

    protected $fillable = [
        'partner_id',
        'title',
        'agreement_type',
        'description',
        'objectives',
        'scope',
        'start_date',
        'end_date',
        'auto_renew',
        'renewal_period_months',
        'document_path',
        'document_name',
        'value',
        'currency',
        'resources_committed',
        'status',
        'signed_date',
        'review_date',
        'manager_id',
        'expiry_notification_sent',
        'internal_notes',
    ];

    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'signed_date' => 'date',
        'review_date' => 'date',
        'auto_renew' => 'boolean',
        'renewal_period_months' => 'integer',
        'value' => 'decimal:2',
        'expiry_notification_sent' => 'boolean',
    ];

    /**
     * Agreement type constants.
     */
    const TYPE_MOU = 'mou';
    const TYPE_MOA = 'moa';
    const TYPE_CONTRACT = 'contract';
    const TYPE_LOI = 'letter_of_intent';
    const TYPE_COLLABORATION = 'collaboration_agreement';
    const TYPE_SPONSORSHIP = 'sponsorship';
    const TYPE_OTHER = 'other';

    /**
     * Status constants.
     */
    const STATUS_DRAFT = 'draft';
    const STATUS_PENDING_SIGNATURE = 'pending_signature';
    const STATUS_ACTIVE = 'active';
    const STATUS_EXPIRED = 'expired';
    const STATUS_TERMINATED = 'terminated';
    const STATUS_UNDER_REVIEW = 'under_review';
    const STATUS_RENEWAL_PENDING = 'renewal_pending';

    /**
     * Get the partner organization.
     */
    public function partner(): BelongsTo
    {
        return $this->belongsTo(RPartner::class, 'partner_id');
    }

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

    /**
     * Scope: Active partnerships.
     */
    public function scopeActive($query)
    {
        return $query->where('status', self::STATUS_ACTIVE);
    }

    /**
     * Scope: Expiring soon.
     */
    public function scopeExpiringSoon($query, int $days = 30)
    {
        return $query->where('status', self::STATUS_ACTIVE)
                     ->whereNotNull('end_date')
                     ->where('end_date', '<=', now()->addDays($days))
                     ->where('end_date', '>=', now());
    }

    /**
     * Scope: Expired.
     */
    public function scopeExpired($query)
    {
        return $query->where('status', self::STATUS_ACTIVE)
                     ->whereNotNull('end_date')
                     ->where('end_date', '<', now());
    }

    /**
     * Scope: By agreement type.
     */
    public function scopeByType($query, string $type)
    {
        return $query->where('agreement_type', $type);
    }

    /**
     * Check if partnership is active.
     */
    public function isActive(): bool
    {
        if ($this->status !== self::STATUS_ACTIVE) {
            return false;
        }

        if ($this->end_date && $this->end_date->isPast()) {
            return false;
        }

        return true;
    }

    /**
     * Check if partnership is expiring soon.
     */
    public function isExpiringSoon(int $days = 30): bool
    {
        if (!$this->end_date || !$this->isActive()) {
            return false;
        }

        return $this->end_date->isPast() === false &&
               $this->end_date->diffInDays(now()) <= $days;
    }

    /**
     * Check if partnership has expired.
     */
    public function hasExpired(): bool
    {
        return $this->end_date && $this->end_date->isPast();
    }

    /**
     * Get days remaining.
     */
    public function getDaysRemainingAttribute(): ?int
    {
        if (!$this->end_date) {
            return null;
        }

        if ($this->end_date->isPast()) {
            return 0;
        }

        return now()->diffInDays($this->end_date);
    }

    /**
     * Get formatted value.
     */
    public function getFormattedValueAttribute(): string
    {
        if (!$this->value) {
            return 'N/A';
        }

        return $this->currency . ' ' . number_format($this->value, 2);
    }

    /**
     * Get agreement type label.
     */
    public function getTypeLabelAttribute(): string
    {
        return match($this->agreement_type) {
            self::TYPE_MOU => 'Memorandum of Understanding',
            self::TYPE_MOA => 'Memorandum of Agreement',
            self::TYPE_CONTRACT => 'Contract',
            self::TYPE_LOI => 'Letter of Intent',
            self::TYPE_COLLABORATION => 'Collaboration Agreement',
            self::TYPE_SPONSORSHIP => 'Sponsorship Agreement',
            default => 'Other',
        };
    }

    /**
     * Get status color.
     */
    public function getStatusColorAttribute(): string
    {
        return match($this->status) {
            self::STATUS_DRAFT => 'gray',
            self::STATUS_PENDING_SIGNATURE => 'yellow',
            self::STATUS_ACTIVE => 'green',
            self::STATUS_EXPIRED => 'red',
            self::STATUS_TERMINATED => 'red',
            self::STATUS_UNDER_REVIEW => 'blue',
            self::STATUS_RENEWAL_PENDING => 'orange',
            default => 'gray',
        };
    }

    /**
     * Renew the partnership.
     */
    public function renew(int $months): void
    {
        $newEndDate = $this->end_date ? 
            $this->end_date->copy()->addMonths($months) : 
            now()->addMonths($months);

        $this->update([
            'end_date' => $newEndDate,
            'status' => self::STATUS_ACTIVE,
            'expiry_notification_sent' => false,
        ]);
    }

    /**
     * Terminate the partnership.
     */
    public function terminate(string $reason = null): void
    {
        $this->update([
            'status' => self::STATUS_TERMINATED,
            'internal_notes' => ($this->internal_notes ?? '') . 
                "\nTerminated: " . now()->format('Y-m-d') . 
                ($reason ? " - {$reason}" : ''),
        ]);
    }
}
