<?php

namespace App\Models;

use Database\Factories\JobSourceFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class JobSource extends Model
{
    /** @use HasFactory<JobSourceFactory> */
    use HasFactory;

    public const TYPE_MANUAL = 'manual';

    public const TYPE_API = 'api';

    public const TYPE_JSON = 'json';

    public const TYPE_RSS = 'rss';

    public const TYPE_XML = 'xml';

    public const AUTH_NONE = 'none';

    public const AUTH_BEARER = 'bearer';

    public const AUTH_API_KEY_HEADER = 'api_key_header';

    public const AUTH_BASIC = 'basic';

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'slug',
        'type',
        'request_method',
        'base_url',
        'feed_url',
        'attribution_text',
        'is_active',
        'auth_type',
        'auth_header_name',
        'auth_username',
        'auth_secret',
        'request_headers',
        'query_parameters',
        'sync_settings',
        'sync_frequency',
        'rate_limit_per_minute',
        'notes',
        'last_synced_at',
        'last_failed_at',
        'last_failure_reason',
    ];

    /**
     * @return HasMany<ImportedJob, $this>
     */
    public function importedJobs(): HasMany
    {
        return $this->hasMany(ImportedJob::class);
    }

    /**
     * @return HasMany<Application, $this>
     */
    public function applications(): HasMany
    {
        return $this->hasMany(Application::class);
    }

    /**
     * @return HasMany<JobSourceSyncLog, $this>
     */
    public function syncLogs(): HasMany
    {
        return $this->hasMany(JobSourceSyncLog::class);
    }

    public function isActive(): bool
    {
        return $this->is_active;
    }

    /**
     * @return array<string, string>
     */
    public static function typeOptions(): array
    {
        return [
            self::TYPE_MANUAL => 'Manual / Employer submitted',
            self::TYPE_API => 'REST API - JSON response',
            self::TYPE_JSON => 'JSON feed',
            self::TYPE_RSS => 'RSS feed',
            self::TYPE_XML => 'XML feed',
        ];
    }

    /**
     * @return array<string, string>
     */
    public static function authOptions(): array
    {
        return [
            self::AUTH_NONE => 'No authentication',
            self::AUTH_BEARER => 'Bearer token',
            self::AUTH_API_KEY_HEADER => 'API key header',
            self::AUTH_BASIC => 'Basic auth',
        ];
    }

    public function isAutomaticallySyncable(): bool
    {
        return in_array($this->type, [
            self::TYPE_API,
            self::TYPE_JSON,
            self::TYPE_RSS,
            self::TYPE_XML,
        ], true);
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'is_active' => 'boolean',
            'auth_secret' => 'encrypted',
            'request_headers' => 'array',
            'query_parameters' => 'array',
            'sync_settings' => 'array',
            'rate_limit_per_minute' => 'integer',
            'last_synced_at' => 'datetime',
            'last_failed_at' => 'datetime',
        ];
    }
}
