﻿<?php

namespace App\Models;

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

class JobDescription extends Model
{
    use HasFactory;
 
    protected $fillable = [
        'organization_id',   // nullable
        'job_title',
        'department',
        'level',
        'location',
        'employment_type',
        'status',
        'created_by',
        'approved_by',
        'approved_at',
        'published_by',
        'published_at',
        'published_link_token',
    ];
 
    protected $casts = [
        'approved_at'  => 'datetime',
        'published_at' => 'datetime',
    ];
 
    // Status Constants
 
    const STATUS_DRAFT     = 'draft';
    const STATUS_APPROVED  = 'approved';
    const STATUS_PUBLISHED = 'published';
 
    // Relationships
 
    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class);
    }
 
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }
 
    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by');
    }
 
    public function publisher(): BelongsTo
    {
        return $this->belongsTo(User::class, 'published_by');
    }
 
    public function sections(): HasMany
    {
        return $this->hasMany(JobDescriptionSection::class)->orderBy('sort_order');
    }
 
    public function coreSections(): HasMany
    {
        return $this->hasMany(JobDescriptionSection::class)
            ->where('is_core', true)
            ->orderBy('sort_order');
    }
 
    public function customSections(): HasMany
    {
        return $this->hasMany(JobDescriptionSection::class)
            ->where('is_core', false)
            ->orderBy('sort_order');
    }
 
    public function versions(): HasMany
    {
        return $this->hasMany(JobDescriptionVersion::class)->orderByDesc('version_number');
    }
 
    public function comments(): HasMany
    {
        return $this->hasMany(JobDescriptionComment::class)
            ->whereNull('parent_id')
            ->orderBy('created_at');
    }
 
    public function allComments(): HasMany
    {
        return $this->hasMany(JobDescriptionComment::class)->orderBy('created_at');
    }
 
    public function exports(): HasMany
    {
        return $this->hasMany(JobDescriptionExport::class);
    }
 
    public function validationChecks(): HasMany
    {
        return $this->hasMany(JobDescriptionValidationCheck::class);
    }
 
    public function activityLog(): HasMany
    {
        return $this->hasMany(JobDescriptionActivityLog::class)->orderBy('created_at');
    }

    /**
     * Get only the most recent entry per event type, ordered chronologically.
     */
    public function latestActivityPerType()
    {
        return $this->activityLog()
            ->whereIn('id', function ($query) {
                $query->selectRaw('MAX(id)')
                    ->from('job_description_activity_log')
                    ->where('job_description_id', $this->id)
                    ->groupBy('event');
            })
            ->orderBy('created_at')
            ->get();
    }
 
    // Scopes
 
    public function scopeForOrganization($query, int $organizationId)
    {
        return $query->where('organization_id', $organizationId);
    }
 
    public function scopeForUser($query, int $userId)
    {
        return $query->where('created_by', $userId);
    }
 
    public function scopeDraft($query)     { return $query->where('status', self::STATUS_DRAFT); }
    public function scopeApproved($query)  { return $query->where('status', self::STATUS_APPROVED); }
    public function scopePublished($query) { return $query->where('status', self::STATUS_PUBLISHED); }
 
    // Status Helpers
 
    public function isDraft(): bool     { return $this->status === self::STATUS_DRAFT; }
    public function isApproved(): bool  { return $this->status === self::STATUS_APPROVED; }
    public function isPublished(): bool { return $this->status === self::STATUS_PUBLISHED; }
 
    /**
     * Published JDs are locked, no edits allowed.
     */
    public function canBeEdited(): bool
    {
        return !$this->isPublished();
    }
 
    /**
     * Export and shareable link are only available after publishing.
     */
    public function canBeExported(): bool
    {
        return $this->isPublished();
    }
 
    // Section Helpers
 
    public function getSection(string $sectionType): ?JobDescriptionSection
    {
        return $this->sections()->where('section_type', $sectionType)->first();
    }
 
    /**
     * All five core section types must be present.
     */
    public function isComplete(): bool
    {
        $existing = $this->coreSections()->pluck('section_type')->toArray();
        return empty(array_diff(JobDescriptionSection::SECTION_TYPES, $existing));
    }
 
    // Version Helpers
 
    public function getLatestVersionNumber(): int
    {
        return $this->versions()->max('version_number') ?? 0;
    }
 
    public function toSnapshot(): array
    {
        $this->loadMissing('sections');
 
        return [
            'job_title'       => $this->job_title,
            'organization_id' => $this->organization_id,
            'department'      => $this->department,
            'level'           => $this->level,
            'location'        => $this->location,
            'employment_type' => $this->employment_type,
            'status'          => $this->status,
            'sections'        => $this->sections->map(fn ($s) => [
                'section_type' => $s->section_type,
                'title'        => $s->title,
                'content'      => $s->content,
                'source'       => $s->source,
                'version'      => $s->version,
                'is_core'      => $s->is_core,
            ])->toArray(),
        ];
    