<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Auth;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

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

    const STATUS_PENDING = 'pending';

    const STATUS_ACCEPTED = 'accepted';

    const STATUS_REJECTED = 'rejected';

    const STATUS_ASK_MODIFICATION = 'ask_modification';

    protected $fillable = [
        'name',
        'status',
        'is_locked',
        'licenseable_id',
        'licenseable_type',
        'created_by',
    ];

    protected $casts = [
        'is_locked' => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    protected $attributes = [
        'status' => self::STATUS_PENDING,
    ];

    /**
     * Get the parent licenseable model (WellLicense or StationLicense)
     */
    public function licenseable(): MorphTo
    {
        return $this->morphTo();
    }

    /**
     * Get the creator of the requirement
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Get the requirement file URL
     */
    public function getRequirementFileUrlAttribute(): ?string
    {
        return $this->getFirstMedia('requirement_file')?->getTemporaryUrl(Carbon::now()->addMinutes(30)) ?: null;
    }

    /**
     * Get available statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_PENDING => __('license_requirement.pending'),
            self::STATUS_ACCEPTED => __('license_requirement.accepted'),
            self::STATUS_REJECTED => __('license_requirement.rejected'),
            self::STATUS_ASK_MODIFICATION => __('license_requirement.ask_modification'),
        ];
    }

    /**
     * Accept requirement
     */
    public function accept(string $notes = ''): void
    {
        $oldStatus = $this->status;
        $this->status = self::STATUS_ACCEPTED;
        $this->save();

        // Log the acceptance activity
        activity()
            ->performedOn($this)
            ->causedBy(Auth::user())
            ->event('accepted')
            ->withProperties([
                'old_status' => $oldStatus,
                'new_status' => self::STATUS_ACCEPTED,
                'action' => 'accepted',
                'notes' => $notes,
            ])
            ->log('License requirement accepted');
    }

    /**
     * Reject requirement
     */
    public function reject(string $notes = ''): void
    {
        $oldStatus = $this->status;
        $this->status = self::STATUS_REJECTED;
        $this->save();

        // Log the rejection activity
        activity()
            ->performedOn($this)
            ->causedBy(Auth::user())
            ->event('rejected')
            ->withProperties([
                'old_status' => $oldStatus,
                'new_status' => self::STATUS_REJECTED,
                'action' => 'rejected',
                'notes' => $notes,
            ])
            ->log('License requirement rejected');
    }

    /**
     * Ask for modification
     */
    public function askModification(string $notes = ''): void
    {
        $oldStatus = $this->status;
        $this->status = self::STATUS_ASK_MODIFICATION;
        $this->save();

        // Log the ask modification activity
        activity()
            ->performedOn($this)
            ->causedBy(Auth::user())
            ->event('ask_modification')
            ->withProperties([
                'old_status' => $oldStatus,
                'new_status' => self::STATUS_ASK_MODIFICATION,
                'action' => 'ask_modification',
                'notes' => $notes,
            ])
            ->log('License requirement modification requested');
    }

    /**
     * Check if requirement has a file
     */
    public function hasRequirementFile(): bool
    {
        return $this->getFirstMedia('requirement_file') !== null;
    }

    /**
     * Get the latest file upload date
     */
    public function getLatestFileUploadDateAttribute(): ?Carbon
    {
        $media = $this->getFirstMedia('requirement_file');

        return $media?->created_at;
    }

    /**
     * Collect PDF files from a collection of requirements
     *
     * @param  \Illuminate\Database\Eloquent\Collection  $requirements
     */
    public static function collectPdfFiles($requirements): array
    {
        $pdfFiles = [];

        foreach ($requirements as $requirement) {
            $file = $requirement->getFirstMedia('requirement_file');
            if ($file && $file->mime_type === 'application/pdf') {
                $pdfFiles[] = [
                    'name' => $requirement->name,
                    'media' => $file,
                ];
            }
        }

        return $pdfFiles;
    }

    /**
     * Register media collections for license requirements
     */
    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('requirement_file')
            ->singleFile()
            ->acceptsMimeTypes([
                'application/pdf',
            ]);
    }

    /**
     * Get activity log options
     */
    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->useLogName('license_requirement')
            ->logOnly([
                'name',
                'status',
                'is_locked',
                'licenseable_id',
                'licenseable_type',
            ])
            ->logOnlyDirty();
    }

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

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

        static::updating(function ($model) {
            if ($model->is_locked && $model->isDirty() && ! $model->isDirty('is_locked')) {
                throw new \Exception(__('license_requirement.cannot_edit_locked'));
            }
        });

        static::deleting(function ($model) {
            if ($model->is_locked) {
                throw new \Exception(__('license_requirement.cannot_delete_locked'));
            }
        });
    }
}
