<?php

namespace App\Models\HR;

use App\Models\Tenants\Department;
use App\Models\User;
use App\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Employee extends Model
{
    use ModelTrait;

    protected $table = 'tenant_user_profiles';

    protected $fillable = [
        'tenant_id',
        'user_id',
        'department_id',
        'position_key',
        'job_title_key',
        'work_location_key',
        'employment_type_key',
        'employee_status',
        'manager_user_id',
        'json_extra',
        'profile_photo_path',
        'display_name',
    ];

    protected $casts = [
        'json_extra' => 'array',
        'tenant_id' => 'int',
        'user_id' => 'int',
        'department_id' => 'int',
        'manager_user_id' => 'int',
    ];

    protected $appends = [
        'hire_date',
        'resign_date',
        'position_label',
        'job_title_label',
    ];

    // =========================================================================
    // 관계 정의
    // =========================================================================

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

    public function department(): BelongsTo
    {
        return $this->belongsTo(Department::class, 'department_id');
    }

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

    // =========================================================================
    // json_extra Accessor
    // =========================================================================

    public function getHireDateAttribute(): ?string
    {
        return $this->json_extra['hire_date'] ?? null;
    }

    public function getResignDateAttribute(): ?string
    {
        return $this->json_extra['resign_date'] ?? null;
    }

    public function getAddressAttribute(): ?string
    {
        return $this->json_extra['address'] ?? null;
    }

    public function getEmergencyContactAttribute(): ?string
    {
        return $this->json_extra['emergency_contact'] ?? null;
    }

    public function getResidentNumberAttribute(): ?string
    {
        return $this->json_extra['resident_number'] ?? null;
    }

    public function getBankAccountAttribute(): ?array
    {
        return $this->json_extra['bank_account'] ?? null;
    }

    public function getDependentsAttribute(): array
    {
        return $this->json_extra['dependents'] ?? [];
    }

    public function getPositionLabelAttribute(): ?string
    {
        if (! $this->position_key || ! $this->tenant_id) {
            return $this->position_key;
        }

        $position = Position::where('tenant_id', $this->tenant_id)
            ->where('type', Position::TYPE_RANK)
            ->where('key', $this->position_key)
            ->first();

        return $position?->name ?? $this->position_key;
    }

    public function getJobTitleLabelAttribute(): ?string
    {
        if (! $this->job_title_key || ! $this->tenant_id) {
            return $this->job_title_key;
        }

        $position = Position::where('tenant_id', $this->tenant_id)
            ->where('type', Position::TYPE_TITLE)
            ->where('key', $this->job_title_key)
            ->first();

        return $position?->name ?? $this->job_title_key;
    }

    // =========================================================================
    // json_extra 헬퍼
    // =========================================================================

    public function getJsonExtraValue(string $key, mixed $default = null): mixed
    {
        return $this->json_extra[$key] ?? $default;
    }

    public function setJsonExtraValue(string $key, mixed $value): void
    {
        $extra = $this->json_extra ?? [];
        if ($value === null) {
            unset($extra[$key]);
        } else {
            $extra[$key] = $value;
        }
        $this->json_extra = $extra;
    }

    // =========================================================================
    // 스코프
    // =========================================================================

    public function scopeForTenant($query, ?int $tenantId = null)
    {
        $tenantId = $tenantId ?? session('selected_tenant_id');
        if ($tenantId) {
            return $query->where('tenant_id', $tenantId);
        }

        return $query;
    }

    public function scopeActiveEmployees($query)
    {
        return $query->where('employee_status', 'active');
    }

    public function scopeOnLeave($query)
    {
        return $query->where('employee_status', 'leave');
    }

    public function scopeResigned($query)
    {
        return $query->where('employee_status', 'resigned');
    }
}
