<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Auth;
use Monzer\FilamentWorkflows\Traits\TrackWorkflowModelEvents;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class ProjectCharterCompletionRequest extends Model implements HasMedia
{
    use HasFactory, InteractsWithMedia, LogsActivity, TrackWorkflowModelEvents;

    const TYPE_COMPLETE = 'complete';

    const TYPE_CANCEL = 'cancel';

    const TYPE_SUSPEND = 'suspend';

    const STATUS_PENDING = 'pending';

    const STATUS_APPROVED = 'approved';

    const STATUS_REJECTED = 'rejected';

    protected $fillable = [
        'project_charter_id',
        'type',
        'status',
        'reason',
        'requested_by',
        'reviewed_by',
        'review_notes',
        'reviewed_at',
        'actual_end_date',
        'learned_lessons',
        'notes',
    ];

    protected $casts = [
        'reviewed_at' => 'datetime',
        'actual_end_date' => 'date',
    ];

    public function projectCharter(): BelongsTo
    {
        return $this->belongsTo(ProjectCharter::class);
    }

    public function requestedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'requested_by');
    }

    public function reviewedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'reviewed_by');
    }

    /**
     * Register media collections
     */
    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('closure_attachments')
            ->acceptsMimeTypes([
                'application/pdf',
                'image/jpeg',
                'image/png',
            ]);
    }

    /**
     * Register media conversions
     */
    public function registerMediaConversions(?Media $media = null): void
    {
        // Add any image conversions if needed
        $this->addMediaConversion('thumb')
            ->width(300)
            ->height(300)
            ->sharpen(10)
            ->performOnCollections('closure_attachments')
            ->nonQueued();
    }

    /**
     * Get available types
     */
    public static function getTypes(): array
    {
        return [
            self::TYPE_COMPLETE => __('project_charter_completion_request.type_complete'),
            self::TYPE_CANCEL => __('project_charter_completion_request.type_cancel'),
            self::TYPE_SUSPEND => __('project_charter_completion_request.type_suspend'),
        ];
    }

    /**
     * Get available statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_PENDING => __('project_charter_completion_request.status_pending'),
            self::STATUS_APPROVED => __('project_charter_completion_request.status_approved'),
            self::STATUS_REJECTED => __('project_charter_completion_request.status_rejected'),
        ];
    }

    /**
     * Check if request can be approved
     */
    public function canApprove(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * Check if request can be rejected
     */
    public function canReject(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * Approve the request
     */
    public function approve(string $reviewNotes = ''): bool
    {
        if (! $this->canApprove()) {
            return false;
        }

        $this->status = self::STATUS_APPROVED;
        $this->reviewed_by = Auth::id();
        $this->review_notes = $reviewNotes;
        $this->reviewed_at = now();

        $result = $this->save();

        if ($result) {
            // Update the project charter status
            $newCharterStatus = match ($this->type) {
                self::TYPE_COMPLETE => ProjectCharter::STATUS_COMPLETED,
                self::TYPE_CANCEL => ProjectCharter::STATUS_CANCELED,
                self::TYPE_SUSPEND => ProjectCharter::STATUS_SUSPENDED,
            };

            $this->projectCharter->update(['status' => $newCharterStatus]);

            // Log activity
            activity()
                ->performedOn($this)
                ->causedBy(Auth::user())
                ->event('approved')
                ->withProperties([
                    'type' => $this->type,
                    'review_notes' => $reviewNotes,
                    'charter_new_status' => $newCharterStatus,
                ])
                ->log('Completion request approved');
        }

        return $result;
    }

    /**
     * Reject the request
     */
    public function reject(string $reviewNotes): bool
    {
        if (! $this->canReject()) {
            return false;
        }

        $this->status = self::STATUS_REJECTED;
        $this->reviewed_by = Auth::id();
        $this->review_notes = $reviewNotes;
        $this->reviewed_at = now();

        $result = $this->save();

        if ($result) {
            // Log activity
            activity()
                ->performedOn($this)
                ->causedBy(Auth::user())
                ->event('rejected')
                ->withProperties([
                    'type' => $this->type,
                    'review_notes' => $reviewNotes,
                ])
                ->log('Completion request rejected');
        }

        return $result;
    }

    /**
     * Configure activity logging
     */
    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly([
                'status',
                'type',
                'reason',
                'actual_end_date',
                'learned_lessons',
                'notes',
            ])
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }

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

        static::creating(function ($model) {
            if (Auth::check()) {
                $model->requested_by = Auth::id();
            }
        });
    }
}
