<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class ApplicantResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        $user = $request->user();
        $canSeeSensitive = $user?->can('viewSensitive', $this->resource) ?? false;

        return [
            'id' => $this->uuid,
            'reference_no' => $this->reference_no,
            'full_name' => $this->full_name,
            'local_name' => $this->local_name,
            'photo_url' => $this->photo_path ? url('storage/'.$this->photo_path) : null,

            'status' => $this->status->value,
            'status_label' => $this->status->label(),
            'status_reason' => $this->status_reason,
            'allowed_transitions' => array_map(
                fn ($status) => ['value' => $status->value, 'label' => $status->label()],
                $this->status->allowedTransitions(),
            ),
            'is_closed' => $this->status->isClosed(),
            'verified_at' => $this->verified_at?->toIso8601String(),
            'is_merged' => $this->merged_into_id !== null,
            'merged_into' => $this->whenLoaded('mergedInto', fn () => $this->mergedInto ? [
                'id' => $this->mergedInto->uuid,
                'reference_no' => $this->mergedInto->reference_no,
                'full_name' => $this->mergedInto->full_name,
            ] : null),

            'gender' => $this->gender,
            'date_of_birth' => $this->date_of_birth?->toDateString(),
            'age' => $this->age(),
            'marital_status' => $this->marital_status,
            'nationality' => $this->nationality,

            // Identity numbers are masked unless the reader may see sensitive data.
            'national_id' => $canSeeSensitive ? $this->national_id : $this->mask($this->national_id),
            'passport_number' => $canSeeSensitive ? $this->passport_number : $this->mask($this->passport_number),
            'passport_expiry_date' => $this->passport_expiry_date?->toDateString(),
            'passport_status' => $this->passport_status,
            'has_valid_passport' => $this->hasValidPassport(),
            'passport_expiring_soon' => $this->passportExpiresWithin(90),

            'mobile' => $this->mobile,
            'whatsapp' => $this->whatsapp,
            'email' => $this->email,
            'district' => $this->district,

            'occupation' => $this->occupation,
            'desired_occupation' => $this->desired_occupation,
            'experience_years' => $this->experience_years,
            'education_level' => $this->education_level,
            'skills' => $this->skills,
            'has_overseas_experience' => (bool) $this->has_overseas_experience,
            'previous_country' => $this->previous_country,
            'preferred_country' => $this->preferred_country,
            'destination_country' => $this->destination_country,

            'source' => $this->source,
            // Checked against the selected demand when one is loaded (§16).
            'submission_blockers' => $this->submissionBlockers(
                $this->relationLoaded('jobDemand') ? $this->jobDemand : null
            ),

            'pipeline' => $this->whenLoaded('pipeline', fn () => $this->pipeline ? [
                'id' => $this->pipeline->uuid, 'name' => $this->pipeline->name,
            ] : null),
            'current_stage' => $this->whenLoaded('currentStage', fn () => $this->currentStage ? [
                'id' => $this->currentStage->uuid,
                'name' => $this->currentStage->name,
                'applicant_label' => $this->currentStage->publicLabel(),
                'sequence' => $this->currentStage->sequence,
                'is_exception' => (bool) $this->currentStage->is_exception,
                'sla_days' => $this->currentStage->sla_days,
            ] : null),
            'days_in_stage' => $this->when(
                $this->relationLoaded('currentStage'),
                fn () => $this->daysInCurrentStage()
            ),
            'sla_breached' => $this->when(
                $this->relationLoaded('currentStage'),
                fn () => $this->isBreachingStageSla()
            ),

            'agent' => $this->whenLoaded('agent', fn () => $this->agent ? [
                'id' => $this->agent->uuid, 'name' => $this->agent->name, 'agent_code' => $this->agent->agent_code,
            ] : null),
            'branch' => $this->whenLoaded('branch', fn () => $this->branch ? [
                'id' => $this->branch->uuid, 'name' => $this->branch->name,
            ] : null),
            'assigned_staff' => $this->whenLoaded('assignedStaff', fn () => $this->assignedStaff ? [
                'id' => $this->assignedStaff->uuid, 'name' => $this->assignedStaff->name,
            ] : null),
            'employer' => $this->whenLoaded('employer', fn () => $this->employer ? [
                'id' => $this->employer->uuid, 'company_name' => $this->employer->company_name,
            ] : null),
            'job_demand' => $this->whenLoaded('jobDemand', fn () => $this->jobDemand ? [
                'id' => $this->jobDemand->uuid,
                'demand_code' => $this->jobDemand->demand_code,
                'job_title' => $this->jobDemand->job_title,
            ] : null),

            // Full detail only for readers allowed to edit the file.
            $this->mergeWhen($user?->can('applicant.update'), fn () => [
                'father_name' => $this->father_name,
                'mother_name' => $this->mother_name,
                'spouse_name' => $this->spouse_name,
                'blood_group' => $this->blood_group,
                'religion' => $this->religion,
                'birth_registration_no' => $this->birth_registration_no,
                'passport_issue_date' => $this->passport_issue_date?->toDateString(),
                'passport_issue_place' => $this->passport_issue_place,
                'present_address' => $this->present_address,
                'permanent_address' => $this->permanent_address,
                'police_station' => $this->police_station,
                'postal_code' => $this->postal_code,
                'emergency_contact_name' => $this->emergency_contact_name,
                'emergency_contact_relation' => $this->emergency_contact_relation,
                'emergency_contact_mobile' => $this->emergency_contact_mobile,
                'certifications' => $this->certifications,
                'languages' => $this->languages,
                'previous_employer' => $this->previous_employer,
                'employment_status' => $this->employment_status,
                'expected_salary_amount' => $this->expected_salary_amount,
                'expected_salary_currency' => $this->expected_salary_currency,
                'expected_fee_amount' => $this->expected_fee_amount,
                'fee_currency' => $this->fee_currency,
                'driving_license_no' => $this->driving_license_no,
                'driving_license_type' => $this->driving_license_type,
                'referral_name' => $this->referral_name,
                'campaign' => $this->campaign,
                'notes' => $this->notes,
            ]),

            'created_at' => $this->created_at?->toIso8601String(),
            'updated_at' => $this->updated_at?->toIso8601String(),
        ];
    }

    /** Shows enough to recognise a record without exposing the number itself. */
    private function mask(?string $value): ?string
    {
        if (blank($value)) {
            return $value;
        }

        $length = mb_strlen($value);

        if ($length <= 4) {
            return str_repeat('*', $length);
        }

        return mb_substr($value, 0, 2).str_repeat('*', $length - 4).mb_substr($value, -2);
    }
}
