<?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\SoftDeletes;
use Illuminate\Support\Str;

class CompanyEmployee extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'company_id',
        'portal_user_id',
        'first_name',
        'last_name',
        'email',
        'date_of_birth',
        'nin_encrypted',
        'is_nin_verified',
        'is_validated',
        'nin_verification_token',
        'nin_verified_at',
        'nin_firstname',
        'nin_middlename',
        'nin_surname',
        'nin_phone',
        'nin_gender',
        'nin_birthdate',
        'nin_birthcountry',
        'nin_birthstate',
        'nin_birthlga',
        'nin_residence_state',
        'nin_residence_town',
        'nin_residence_lga',
        'nin_residence_address',
        'nin_photo',
        'nin_report_id',
        'phone',
        'employee_number',
        'department',
        'position',
        'hire_date',
        'employment_status',
        'submission_token',
        'submission_token_sent_at',
        'submission_token_used_at',
    ];

    protected function casts(): array
    {
        return [
            'date_of_birth' => 'date',
            'hire_date' => 'date',
            'nin_birthdate' => 'date',
            'is_nin_verified' => 'boolean',
            'is_validated' => 'boolean',
            'nin_verified_at' => 'datetime',
            'submission_token_sent_at' => 'datetime',
            'submission_token_used_at' => 'datetime',
        ];
    }

    /**
     * Get the company that owns the employee.
     */
    public function company(): BelongsTo
    {
        return $this->belongsTo(Company::class);
    }

    /**
     * Get the portal user associated with the employee.
     */
    public function portalUser(): BelongsTo
    {
        return $this->belongsTo(PortalUser::class);
    }

    /**
     * Get the employee's full name.
     */
    public function getFullNameAttribute(): string
    {
        return "{$this->first_name} {$this->last_name}";
    }

    /**
     * Check if employee is active.
     */
    public function isActive(): bool
    {
        return $this->employment_status === 'active';
    }

    /**
     * Check if employee has portal access.
     */
    public function hasPortalAccess(): bool
    {
        return ! is_null($this->portal_user_id);
    }

    /**
     * Check if employee's NIN has been verified.
     */
    public function isNinVerified(): bool
    {
        return $this->is_nin_verified === true;
    }

    /**
     * Check if employee has submitted their NIN.
     */
    public function hasSubmittedNin(): bool
    {
        return ! is_null($this->nin_encrypted);
    }

    /**
     * Get the beneficiaries for the employee.
     */
    public function beneficiaries()
    {
        return $this->hasMany(Beneficiary::class);
    }

    /**
     * Generate a new 64-char submission token and record when it was sent.
     */
    public function generateSubmissionToken(): string
    {
        $token = Str::random(64);

        $this->update([
            'submission_token' => $token,
            'submission_token_sent_at' => now(),
            'submission_token_used_at' => null,
        ]);

        return $token;
    }

    /**
     * Whether the submission token has expired (7-day window).
     */
    public function hasExpiredSubmissionToken(): bool
    {
        return $this->submission_token_sent_at === null
            || $this->submission_token_sent_at->addDays(7)->isPast();
    }

    /**
     * Whether the employee has already used their submission token.
     */
    public function hasUsedSubmissionToken(): bool
    {
        return $this->submission_token_used_at !== null;
    }

    /**
     * Mark the submission token as used (one-time use).
     */
    public function markSubmissionTokenUsed(): void
    {
        $this->update(['submission_token_used_at' => now()]);
    }
}
