<?php

namespace App\Models\Tenants;

use App\Models\Members\User;
use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 테넌트별 사용자 프로필 (사원 정보)
 *
 * @property int $id
 * @property int $tenant_id
 * @property int $user_id
 * @property int|null $department_id
 * @property string $employee_status active|leave|resigned
 * @property array|null $json_extra
 *
 * @mixin IdeHelperTenantUserProfile
 */
class TenantUserProfile extends Model
{
    use Auditable;
    protected $casts = [
        'json_extra' => 'array',
    ];

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

    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',
        'worker_type',
        'profile_photo_path',
        'display_name',
    ];

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

    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');
    }

    /**
     * 직급 (positions 테이블 type=rank)
     */
    public function rankPosition(): BelongsTo
    {
        return $this->belongsTo(Position::class, 'position_key', 'key')
            ->where('type', Position::TYPE_RANK)
            ->where('tenant_id', $this->tenant_id);
    }

    /**
     * 직책 (positions 테이블 type=title)
     */
    public function titlePosition(): BelongsTo
    {
        return $this->belongsTo(Position::class, 'job_title_key', 'key')
            ->where('type', Position::TYPE_TITLE)
            ->where('tenant_id', $this->tenant_id);
    }

    // =========================================================================
    // json_extra 헬퍼 메서드
    // =========================================================================

    /**
     * json_extra에서 특정 키 값 가져오기
     */
    public function getJsonExtraValue(string $key, mixed $default = null): mixed
    {
        return $this->json_extra[$key] ?? $default;
    }

    /**
     * json_extra에 특정 키 값 설정
     */
    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;
    }

    /**
     * 사원 정보 일괄 업데이트 (json_extra)
     */
    public function updateEmployeeInfo(array $data): void
    {
        $allowedKeys = [
            'employee_code',
            'resident_number',
            'gender',
            'address',
            'salary',
            'hire_date',
            'rank',
            'bank_account',
            'work_type',
            'contract_info',
            'emergency_contact',
            'education',
            'certifications',
        ];

        $extra = $this->json_extra ?? [];
        foreach ($allowedKeys as $key) {
            if (array_key_exists($key, $data)) {
                if ($data[$key] === null) {
                    unset($extra[$key]);
                } else {
                    $extra[$key] = $data[$key];
                }
            }
        }
        $this->json_extra = $extra;
        $this->save();
    }

    // =========================================================================
    // json_extra Accessor (자주 사용하는 필드)
    // =========================================================================

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

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

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

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

    /**
     * 직급 레이블 (position_key → positions 테이블에서 name 조회)
     */
    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;
    }

    /**
     * 직책 레이블 (job_title_key → positions 테이블에서 name 조회)
     */
    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 내 직급 정보 (rank)
     */
    public function getRankAttribute(): ?string
    {
        return $this->json_extra['rank'] ?? null;
    }

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

    public function scopeActive($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');
    }
}
