<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * LeadershipAssignment Model
 *
 * Represents the assignment of a user to a leadership position.
 * Tracks start and end dates and whether the assignment is current.
 * Automatically creates leadership history when an assignment ends.
 *
 * @property int $id
 * @property int $leadership_position_id
 * @property int $user_id
 * @property \Illuminate\Support\Carbon $start_date
 * @property \Illuminate\Support\Carbon|null $end_date
 * @property bool $is_current
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $deleted_at
 */
class LeadershipAssignment extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'leadership_position_id',
        'user_id',
        'start_date',
        'end_date',
        'is_current',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'is_current' => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    /**
     * The "booted" method of the model.
     *
     * Sets up model event listeners for automatic history creation.
     */
    protected static function booted(): void
    {
        static::updating(function (LeadershipAssignment $assignment) {
            // When assignment is ending, create a history record
            if ($assignment->isDirty('is_current') && !$assignment->is_current) {
                static::createHistoryRecord($assignment);
            }
        });

        static::deleting(function (LeadershipAssignment $assignment) {
            // When deleting a current assignment, create a history record
            if ($assignment->is_current) {
                static::createHistoryRecord($assignment);
            }
        });
    }

    /**
     * Create a leadership history record from an assignment.
     *
     * @param LeadershipAssignment $assignment
     * @return LeadershipHistory
     */
    protected static function createHistoryRecord(LeadershipAssignment $assignment): LeadershipHistory
    {
        return LeadershipHistory::create([
            'organization_id' => $assignment->leadershipPosition->organization_id,
            'leadership_position_id' => $assignment->leadership_position_id,
            'user_id' => $assignment->user_id,
            'term_start_date' => $assignment->start_date,
            'term_end_date' => $assignment->end_date ?? now(),
            'position_title' => $assignment->leadershipPosition->title,
        ]);
    }

    /**
     * Get the leadership position for this assignment.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function leadershipPosition()
    {
        return $this->belongsTo(LeadershipPosition::class);
    }

    /**
     * Get the user assigned to this position.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get the organization through the leadership position.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
     */
    public function organization()
    {
        return $this->hasOneThrough(
            Organization::class,
            LeadershipPosition::class,
            'id',
            'id',
            'leadership_position_id',
            'organization_id'
        );
    }

    /**
     * End this assignment and create a history record.
     *
     * @param \Illuminate\Support\Carbon|null $endDate
     * @return bool
     */
    public function end(?string $endDate = null): bool
    {
        $this->is_current = false;
        $this->end_date = $endDate ?? now()->toDateString();
        return $this->save();
    }

    /**
     * Get the duration of this assignment in days.
     *
     * @return int|null
     */
    public function getDurationInDays(): ?int
    {
        if ($this->end_date) {
            return $this->start_date->diffInDays($this->end_date);
        }
        return null; // Still ongoing
    }

    /**
     * Get the duration of this assignment in a human-readable format.
     *
     * @return string
     */
    public function getDurationAttribute(): string
    {
        $endDate = $this->end_date ?? now();
        return $this->start_date->diffForHumans($endDate, true);
    }

    /**
     * Scope to get only current assignments.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeCurrent($query)
    {
        return $query->where('is_current', true);
    }

    /**
     * Scope to get only past assignments.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePast($query)
    {
        return $query->where('is_current', false);
    }

    /**
     * Scope to get assignments for a specific position.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $positionId
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeForPosition($query, int $positionId)
    {
        return $query->where('leadership_position_id', $positionId);
    }

    /**
     * Scope to get assignments for a specific user.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $userId
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeForUser($query, int $userId)
    {
        return $query->where('user_id', $userId);
    }
}
