<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Worker;
use App\Models\WorkerCategory;
use App\Models\Shortlist;
use App\Models\JobOffer;
use App\Models\JobApplication;
use App\Models\JobPost;
use App\Models\Review;
use App\Models\ProfileView;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class EmployerWorkerController extends Controller
{
    /**
     * Helper to map worker DB models to API presentation format.
     */
    private function formatWorker(Worker $w)
    {
        // Map languages with country names
        $langs = ($w->id % 2 === 0) ? ['English', 'Arabic'] : (($w->id % 3 === 0) ? ['English', 'Tagalog'] : ['English', 'Hindi', 'Arabic']);
        
        // Preferred job types: full-time / part-time / live-in / live-out
        $jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
        $preferredJobType = $w->preferred_job_type ?? $jobTypes[$w->id % 4];

        // Emirates ID verification status (dynamic passport status)
        $emiratesIdStatus = $w->emirates_id_status;

        // Exact Skills mapping: cooking, driving, childcare, cleaning, elderly care, gardening
        $skillsList = ['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'];
        $mappedSkills = [
            $skillsList[$w->id % 6],
            $skillsList[($w->id + 2) % 6]
        ];

        // Visa status
        $visaStatus = $w->visa_status;

        // Optional profile photos
        $photos = [
            'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=200',
            'https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&q=80&w=200',
            'https://images.unsplash.com/photo-1544005313-94ddf0286df2?auto=format&fit=crop&q=80&w=200',
            null
        ];
        $photo = $photos[$w->id % 4];

        $dbReviews = \App\Models\Review::where('worker_id', $w->id)->get();
        $reviewsCount = $dbReviews->count();
        $rating = $reviewsCount > 0 ? round($dbReviews->avg('rating'), 1) : 0.0;

        return [
            'id' => $w->id,
            'name' => $w->name,
            'nationality' => $w->nationality,
            'photo' => $photo,
            'emirates_id_status' => $emiratesIdStatus,
            'passport_status' => $w->passport_status,
            'skills' => $mappedSkills,
            'visa_status' => $visaStatus,
            'experience' => $w->experience,
            'religion' => $w->religion,
            'languages' => $langs, 
            'age' => $w->age,
            'verified' => (bool)$w->verified,
            'preferred_job_type' => $preferredJobType,
            'bio' => $w->bio,
            'rating' => $rating,
            'reviews_count' => $reviewsCount,
            'preferred_location' => $w->preferred_location,
            'live_in_out' => $w->live_in_out,
            'in_country' => (bool)$w->in_country,
        ];
    }

    /**
     * 1. GET /api/employers/workers
     * List of workers available for hiring.
     */
    public function getWorkers(Request $request)
    {
        try {
            $query = Worker::with(['category', 'skills', 'documents'])
                ->where('status', '!=', 'Hired')
                ->where('status', '!=', 'hidden');

            // Apply search filter if provided
            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nationality', 'like', "%{$search}%")
                      ->orWhere('religion', 'like', "%{$search}%");
                });
            }

            $dbWorkers = $query->latest()->get();

            $formattedWorkers = $dbWorkers->map(function ($w) {
                $isPending = str_contains(strtolower($w->passport_status), 'pending');
                if ($isPending || $w->status === 'hidden' || $w->status === 'Hired') {
                    return null;
                }
                return $this->formatWorker($w);
            })->filter()->values();

            $workersArray = $formattedWorkers->toArray();

            // Apply filters: skills, language/languages, nationality, preferred_location, job_type, live_in_out, in_country, visa_status
            if ($request->filled('nationality')) {
                $natInput = $request->nationality;
                $natsArray = is_array($natInput) ? $natInput : array_filter(array_map('trim', explode(',', $natInput)));
                $natsArray = array_map('strtolower', $natsArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($natsArray) {
                    if (!isset($c['nationality'])) return false;
                    $wNat = strtolower($c['nationality']);
                    foreach ($natsArray as $n) {
                        if (str_contains($wNat, $n) || $wNat === $n) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            if ($request->filled('skills')) {
                $skills = $request->skills;
                $skillsArray = is_array($skills) ? $skills : array_filter(array_map('trim', explode(',', $skills)));
                $skillsArray = array_map('strtolower', $skillsArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($skillsArray) {
                    if (!isset($c['skills']) || !is_array($c['skills'])) return false;
                    foreach ($c['skills'] as $s) {
                        if (in_array(strtolower($s), $skillsArray)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            $langParam = $request->input('language') ?? $request->input('languages');
            if ($langParam) {
                $langsArray = is_array($langParam) ? $langParam : array_filter(array_map('trim', explode(',', $langParam)));
                $langsArray = array_map('strtolower', $langsArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($langsArray) {
                    if (!isset($c['languages']) || !is_array($c['languages'])) return false;
                    foreach ($c['languages'] as $l) {
                        if (in_array(strtolower($l), $langsArray)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: preferred_location
            if ($request->filled('preferred_location')) {
                $prefLoc = $request->preferred_location;
                $locsArray = is_array($prefLoc) ? $prefLoc : array_filter(array_map('trim', explode(',', $prefLoc)));
                $locsArray = array_map('strtolower', $locsArray);
                
                $workersArray = array_values(array_filter($workersArray, function ($c) use ($locsArray) {
                    if (!isset($c['preferred_location'])) return false;
                    $wLoc = strtolower($c['preferred_location']);
                    foreach ($locsArray as $l) {
                        if (str_contains($wLoc, $l)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: job_type / preferred_job_type
            $jobTypeParam = $request->input('job_type') ?? $request->input('preferred_job_type');
            if ($jobTypeParam) {
                $jobTypesArray = is_array($jobTypeParam) ? $jobTypeParam : array_filter(array_map('trim', explode(',', $jobTypeParam)));
                $jobTypesArray = array_map('strtolower', $jobTypesArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($jobTypesArray) {
                    if (!isset($c['preferred_job_type'])) return false;
                    $wJobType = strtolower($c['preferred_job_type']);
                    foreach ($jobTypesArray as $jt) {
                        if (str_contains($wJobType, $jt)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: accommodation_type / accomadation_type / live_in_out
            $accParam = $request->input('live_in_out') ?? $request->input('accommodation_type') ?? $request->input('accomadation_type');
            if ($accParam) {
                $accsArray = is_array($accParam) ? $accParam : array_filter(array_map('trim', explode(',', $accParam)));
                $accsArray = array_map(function($val) {
                    return str_replace(['_', '-'], ' ', strtolower($val));
                }, $accsArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($accsArray) {
                    if (!isset($c['live_in_out'])) return false;
                    $wAcc = str_replace(['_', '-'], ' ', strtolower($c['live_in_out']));
                    foreach ($accsArray as $a) {
                        if (str_contains($wAcc, $a)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: in country / out country (in_country / out_country)
            if ($request->has('in_country')) {
                $inCountryVal = $request->input('in_country');
                if ($inCountryVal !== null && $inCountryVal !== '') {
                    $isInCountry = filter_var($inCountryVal, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
                    if ($isInCountry === null) {
                        $strVal = strtolower(trim($inCountryVal));
                        if ($strVal === 'in' || $strVal === 'in_country' || $strVal === 'yes') {
                            $isInCountry = true;
                        } elseif ($strVal === 'out' || $strVal === 'out_country' || $strVal === 'no') {
                            $isInCountry = false;
                        }
                    }
                    if ($isInCountry !== null) {
                        $workersArray = array_values(array_filter($workersArray, function ($c) use ($isInCountry) {
                            return isset($c['in_country']) && (bool)$c['in_country'] === $isInCountry;
                        }));
                    }
                }
            }

            if ($request->has('out_country')) {
                $outCountryVal = $request->input('out_country');
                if ($outCountryVal !== null && $outCountryVal !== '') {
                    $isOutCountry = filter_var($outCountryVal, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
                    if ($isOutCountry === null) {
                        $strVal = strtolower(trim($outCountryVal));
                        if ($strVal === 'out' || $strVal === 'out_country' || $strVal === 'yes') {
                            $isOutCountry = true;
                        } elseif ($strVal === 'in' || $strVal === 'in_country' || $strVal === 'no') {
                            $isOutCountry = false;
                        }
                    }
                    if ($isOutCountry !== null) {
                        $workersArray = array_values(array_filter($workersArray, function ($c) use ($isOutCountry) {
                            return isset($c['in_country']) && (bool)$c['in_country'] !== $isOutCountry;
                        }));
                    }
                }
            }

            // Filter: visa_status / next_visa_type / visa_type (applicable when in country)
            $visaParam = $request->input('visa_status') ?? $request->input('next_visa_type') ?? $request->input('visa_type');
            if ($visaParam) {
                $visasArray = is_array($visaParam) ? $visaParam : array_filter(array_map('trim', explode(',', $visaParam)));
                $visasArray = array_map('strtolower', $visasArray);

                $workersArray = array_values(array_filter($workersArray, function ($c) use ($visasArray) {
                    if (!isset($c['visa_status'])) return false;
                    $isInCountry = isset($c['in_country']) && (bool)$c['in_country'];
                    if (!$isInCountry) {
                        return false;
                    }
                    $wVisa = strtolower($c['visa_status']);
                    foreach ($visasArray as $v) {
                        if (str_contains($wVisa, $v)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            return response()->json([
                'success' => true,
                'data' => [
                    'workers' => $workersArray
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Get Workers Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching the worker list.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * 2. GET /api/employers/candidates
     * List of candidates representing standard job applications and direct hiring offers.
     */
    public function getCandidates(Request $request)
    {
        /** @var User $employer */
        $employer = $request->attributes->get('employer');

        try {
            $employerId = $employer->id;

            // Fetch Job Applications
            $jobIds = JobPost::where('employer_id', $employerId)->pluck('id');
            $applicationsQuery = JobApplication::whereIn('job_id', $jobIds)
                ->with(['worker.category', 'jobPost']);

            // Fetch Direct Hiring Offers
            $directOffersQuery = JobOffer::where('employer_id', $employerId)
                ->with('worker.category');

            // Apply search filter if provided
            if ($request->filled('search')) {
                $search = $request->search;
                $applicationsQuery->whereHas('worker', function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nationality', 'like', "%{$search}%")
                      ->orWhere('religion', 'like', "%{$search}%");
                });
                $directOffersQuery->whereHas('worker', function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('nationality', 'like', "%{$search}%")
                      ->orWhere('religion', 'like', "%{$search}%");
                });
            }

            $applications = $applicationsQuery->get();

            $selectedWorkers = $applications->map(function ($app) {
                $w = $app->worker;
                if (!$w) return null;

                $status = 'Reviewing';
                if ($app->status === 'hired') $status = 'Hired';
                elseif ($app->status === 'rejected') $status = 'Rejected';
                elseif ($app->status === 'shortlisted' || $app->status === 'offer_sent') $status = 'Offer Sent';
                elseif ($app->status === 'applied') $status = 'Reviewing';
                else $status = ucfirst($app->status);

                $langs = ($w->id % 2 === 0) ? ['English', 'Arabic'] : (($w->id % 3 === 0) ? ['English', 'Tagalog'] : ['English', 'Hindi', 'Arabic']);
                $skillsList = ['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'];
                $mappedSkills = [
                    $skillsList[$w->id % 6],
                    $skillsList[($w->id + 2) % 6]
                ];
                $jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
                $preferredJobType = $w->preferred_job_type ?? $jobTypes[$w->id % 4];

                return [
                    'id' => $app->id,
                    'worker_id' => $w->id,
                    'name' => $w->name,
                    'nationality' => $w->nationality,
                    'status' => $status,
                    'applied_at' => $app->created_at->format('Y-m-d H:i:s'),
                    'type' => 'application',
                    'skills' => $mappedSkills,
                    'languages' => $langs,
                    'availability' => $w->availability ?? 'Immediate',
                    'preferred_location' => $w->preferred_location,
                    'preferred_job_type' => $preferredJobType,
                    'live_in_out' => $w->live_in_out,
                    'in_country' => (bool)$w->in_country,
                    'visa_status' => $w->visa_status,
                ];
            })->filter()->values()->toArray();

            // Fetch Direct Hiring Offers
            $directOffers = $directOffersQuery->get();

            $directWorkers = $directOffers->map(function ($offer) {
                $w = $offer->worker;
                if (!$w) return null;

                $status = 'Offer Sent';
                if ($offer->status === 'accepted') $status = 'Hired';
                elseif ($offer->status === 'rejected') $status = 'Rejected';
                elseif ($offer->status === 'pending') $status = 'Offer Sent';

                $langs = ($w->id % 2 === 0) ? ['English', 'Arabic'] : (($w->id % 3 === 0) ? ['English', 'Tagalog'] : ['English', 'Hindi', 'Arabic']);
                $skillsList = ['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'];
                $mappedSkills = [
                    $skillsList[$w->id % 6],
                    $skillsList[($w->id + 2) % 6]
                ];
                $jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
                $preferredJobType = $w->preferred_job_type ?? $jobTypes[$w->id % 4];

                return [
                    'id' => 'offer_' . $offer->id,
                    'worker_id' => $w->id,
                    'name' => $w->name,
                    'nationality' => $w->nationality,
                    'status' => $status,
                    'applied_at' => $offer->created_at->format('Y-m-d H:i:s'),
                    'type' => 'direct_offer',
                    'skills' => $mappedSkills,
                    'languages' => $langs,
                    'availability' => $w->availability ?? 'Immediate',
                    'preferred_location' => $w->preferred_location,
                    'preferred_job_type' => $preferredJobType,
                    'live_in_out' => $w->live_in_out,
                    'in_country' => (bool)$w->in_country,
                    'visa_status' => $w->visa_status,
                ];
            })->filter()->values()->toArray();

            // Merge and sort
            $mergedCandidates = array_merge($selectedWorkers, $directWorkers);

            // Only display Hired candidates in the candidates pipeline (exclude active states)
            $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) {
                return $c && $c['status'] === 'Hired';
            }));

            // Apply filters: skills, languages, nationality, availability, preferred_location, job_type, live_in_out, in_country, visa_status
            if ($request->filled('nationality')) {
                $natInput = $request->nationality;
                $natsArray = is_array($natInput) ? $natInput : array_filter(array_map('trim', explode(',', $natInput)));
                $natsArray = array_map('strtolower', $natsArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($natsArray) {
                    if (!isset($c['nationality'])) return false;
                    $wNat = strtolower($c['nationality']);
                    foreach ($natsArray as $n) {
                        if (str_contains($wNat, $n) || $wNat === $n) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            if ($request->filled('availability')) {
                $availability = strtolower($request->availability);
                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($availability) {
                    return isset($c['availability']) && strtolower($c['availability']) === $availability;
                }));
            }

            if ($request->filled('skills')) {
                $skills = $request->skills;
                $skillsArray = is_array($skills) ? $skills : array_filter(array_map('trim', explode(',', $skills)));
                $skillsArray = array_map('strtolower', $skillsArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($skillsArray) {
                    if (!isset($c['skills']) || !is_array($c['skills'])) return false;
                    foreach ($c['skills'] as $s) {
                        if (in_array(strtolower($s), $skillsArray)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            if ($request->filled('languages')) {
                $languages = $request->languages;
                $langsArray = is_array($languages) ? $languages : array_filter(array_map('trim', explode(',', $languages)));
                $langsArray = array_map('strtolower', $langsArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($langsArray) {
                    if (!isset($c['languages']) || !is_array($c['languages'])) return false;
                    foreach ($c['languages'] as $l) {
                        if (in_array(strtolower($l), $langsArray)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: preferred_location
            if ($request->filled('preferred_location')) {
                $prefLoc = $request->preferred_location;
                $locsArray = is_array($prefLoc) ? $prefLoc : array_filter(array_map('trim', explode(',', $prefLoc)));
                $locsArray = array_map('strtolower', $locsArray);
                
                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($locsArray) {
                    if (!isset($c['preferred_location'])) return false;
                    $wLoc = strtolower($c['preferred_location']);
                    foreach ($locsArray as $l) {
                        if (str_contains($wLoc, $l)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: job_type / preferred_job_type
            $jobTypeParam = $request->input('job_type') ?? $request->input('preferred_job_type');
            if ($jobTypeParam) {
                $jobTypesArray = is_array($jobTypeParam) ? $jobTypeParam : array_filter(array_map('trim', explode(',', $jobTypeParam)));
                $jobTypesArray = array_map('strtolower', $jobTypesArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($jobTypesArray) {
                    if (!isset($c['preferred_job_type'])) return false;
                    $wJobType = strtolower($c['preferred_job_type']);
                    foreach ($jobTypesArray as $jt) {
                        if (str_contains($wJobType, $jt)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: accommodation_type / accomadation_type / live_in_out
            $accParam = $request->input('live_in_out') ?? $request->input('accommodation_type') ?? $request->input('accomadation_type');
            if ($accParam) {
                $accsArray = is_array($accParam) ? $accParam : array_filter(array_map('trim', explode(',', $accParam)));
                $accsArray = array_map(function($val) {
                    return str_replace(['_', '-'], ' ', strtolower($val));
                }, $accsArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($accsArray) {
                    if (!isset($c['live_in_out'])) return false;
                    $wAcc = str_replace(['_', '-'], ' ', strtolower($c['live_in_out']));
                    foreach ($accsArray as $a) {
                        if (str_contains($wAcc, $a)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            // Filter: in country / out country (in_country / out_country)
            if ($request->has('in_country')) {
                $inCountryVal = $request->input('in_country');
                if ($inCountryVal !== null && $inCountryVal !== '') {
                    $isInCountry = filter_var($inCountryVal, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
                    if ($isInCountry === null) {
                        $strVal = strtolower(trim($inCountryVal));
                        if ($strVal === 'in' || $strVal === 'in_country' || $strVal === 'yes') {
                            $isInCountry = true;
                        } elseif ($strVal === 'out' || $strVal === 'out_country' || $strVal === 'no') {
                            $isInCountry = false;
                        }
                    }
                    if ($isInCountry !== null) {
                        $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($isInCountry) {
                            return isset($c['in_country']) && (bool)$c['in_country'] === $isInCountry;
                        }));
                    }
                }
            }

            if ($request->has('out_country')) {
                $outCountryVal = $request->input('out_country');
                if ($outCountryVal !== null && $outCountryVal !== '') {
                    $isOutCountry = filter_var($outCountryVal, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
                    if ($isOutCountry === null) {
                        $strVal = strtolower(trim($outCountryVal));
                        if ($strVal === 'out' || $strVal === 'out_country' || $strVal === 'yes') {
                            $isOutCountry = true;
                        } elseif ($strVal === 'in' || $strVal === 'in_country' || $strVal === 'no') {
                            $isOutCountry = false;
                        }
                    }
                    if ($isOutCountry !== null) {
                        $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($isOutCountry) {
                            return isset($c['in_country']) && (bool)$c['in_country'] !== $isOutCountry;
                        }));
                    }
                }
            }

            // Filter: visa_status / next_visa_type / visa_type (applicable when in country)
            $visaParam = $request->input('visa_status') ?? $request->input('next_visa_type') ?? $request->input('visa_type');
            if ($visaParam) {
                $visasArray = is_array($visaParam) ? $visaParam : array_filter(array_map('trim', explode(',', $visaParam)));
                $visasArray = array_map('strtolower', $visasArray);

                $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($visasArray) {
                    if (!isset($c['visa_status'])) return false;
                    $isInCountry = isset($c['in_country']) && (bool)$c['in_country'];
                    if (!$isInCountry) {
                        return false;
                    }
                    $wVisa = strtolower($c['visa_status']);
                    foreach ($visasArray as $v) {
                        if (str_contains($wVisa, $v)) {
                            return true;
                        }
                    }
                    return false;
                }));
            }

            $page = (int)$request->input('page', 1);
            $perPage = (int)$request->input('per_page', 15);
            $total = count($mergedCandidates);
            $offset = ($page - 1) * $perPage;
            $paginatedCandidates = array_slice($mergedCandidates, $offset, $perPage);

            return response()->json([
                'success' => true,
                'data' => [
                    'candidates' => $paginatedCandidates,
                    'pagination' => [
                        'total' => $total,
                        'per_page' => $perPage,
                        'current_page' => $page,
                        'last_page' => max(1, (int)ceil($total / $perPage)),
                    ]
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Get Candidates Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching the candidate list.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * 3. POST /api/employers/candidates/hire or POST /api/employers/candidates/{id}/hire
     * Update status from active (or reviewing/pending) to hired.
     */
    public function hireCandidate(Request $request, $id = null)
    {
        /** @var User $employer */
        $employer = $request->attributes->get('employer');

        // Let the client pass either route parameter id OR body parameter identifier
        $targetId = $id ?: $request->input('id') ?: $request->input('worker_id') ?: $request->input('application_id') ?: $request->input('offer_id');

        if (!$targetId) {
            return response()->json([
                'success' => false,
                'message' => 'Candidate or Worker identifier is required.'
            ], 422);
        }

        try {
            $employerId = $employer->id;
            $worker = null;
            $updatedApplication = null;
            $updatedOffer = null;

            // Direct Offer check
            if (is_string($targetId) && str_starts_with($targetId, 'offer_')) {
                $offerId = substr($targetId, 6);
                $offer = JobOffer::where('id', $offerId)->where('employer_id', $employerId)->firstOrFail();
                
                $offer->update(['status' => 'accepted']);
                if ($offer->worker) {
                    $offer->worker->update(['status' => 'Hired']);
                    $worker = $offer->worker;
                }
                $updatedOffer = $offer;
            } else {
                // Check if targetId is an application
                $application = JobApplication::where('id', $targetId)
                    ->whereHas('jobPost', function($q) use ($employerId) {
                        $q->where('employer_id', $employerId);
                    })->first();

                if ($application) {
                    $application->update(['status' => 'hired']);
                    if ($application->worker) {
                        $application->worker->update(['status' => 'Hired']);
                        $worker = $application->worker;
                    }
                    $updatedApplication = $application;
                } else {
                    // Try targeting by Worker ID directly
                    $worker = Worker::find($targetId);
                    
                    if (!$worker) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Worker, application, or job offer not found with the provided identifier.'
                        ], 404);
                    }

                    $worker->update(['status' => 'Hired']);

                    // Find existing direct offer
                    $offer = JobOffer::where('employer_id', $employerId)
                        ->where('worker_id', $worker->id)
                        ->first();

                    if ($offer) {
                        $offer->update(['status' => 'accepted']);
                        $updatedOffer = $offer;
                    } else {
                        // Find existing application
                        $jobIds = JobPost::where('employer_id', $employerId)->pluck('id');
                        $application = JobApplication::whereIn('job_id', $jobIds)
                            ->where('worker_id', $worker->id)
                            ->first();

                        if ($application) {
                            $application->update(['status' => 'hired']);
                            $updatedApplication = $application;
                        } else {
                            // Create a new direct job offer and accept it
                            $updatedOffer = JobOffer::create([
                                'employer_id' => $employerId,
                                'worker_id' => $worker->id,
                                'work_date' => now()->format('Y-m-d'),
                                'location' => 'Dubai',
                                'salary' => $worker->salary,
                                'notes' => 'Direct sponsoring matching finalized via mobile API.',
                                'status' => 'accepted',
                            ]);
                        }
                    }
                }
            }

            return response()->json([
                'success' => true,
                'message' => 'Candidate successfully marked as Hired!',
                'data' => [
                    'worker_id' => $worker ? $worker->id : null,
                    'worker_status' => $worker ? $worker->status : 'Hired',
                    'application' => $updatedApplication,
                    'offer' => $updatedOffer,
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Hire Candidate Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while marking the candidate as hired.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * 4. GET /api/employers/workers/{id}
     * Get detailed worker profile, mirroring the web detail view.
     */
    public function getWorkerDetail(Request $request, $id)
    {
        /** @var User $employer */
        $employer = $request->attributes->get('employer');
        $w = Worker::with(['category', 'skills', 'documents'])->find($id);

        if (!$w) {
            return response()->json([
                'success' => false,
                'message' => 'Worker profile not found.'
            ], 404);
        }

        try {
            $isPending = str_contains(strtolower($w->passport_status), 'pending');
            if ($w->status === 'hidden' || $isPending) {
                return response()->json([
                    'success' => false,
                    'message' => 'Worker profile not found.'
                ], 404);
            }

            // Record employer profile view (Requirement 3)
            if ($employer) {
                ProfileView::updateOrCreate(
                    ['employer_id' => $employer->id, 'worker_id' => $w->id],
                    ['updated_at' => now()]
                );
            }

            // Map languages
            $langs = ($w->id % 2 === 0) ? ['English', 'Arabic'] : (($w->id % 3 === 0) ? ['English', 'Tagalog'] : ['English', 'Hindi', 'Arabic']);
            
            // Preferred job types
            $jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
            $preferredJobType = $jobTypes[$w->id % 4];

            // Emirates ID status
            $emiratesIdStatus = $w->verified ? 'Emirates ID Verified' : 'EID Verification Pending';

            // Skills mapping
            $skillsList = ['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'];
            $mappedSkills = [
                $skillsList[$w->id % 6],
                $skillsList[($w->id + 2) % 6]
            ];

            // Visa status
            $visaStatusesList = ['Residence Visa', 'Tourist Visa', 'Employment Visa', 'Cancelled Visa', 'Own Visa'];
            $visaStatus = $visaStatusesList[$w->id % 5];

            // Profile photo
            $photos = [
                'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=200',
                'https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&q=80&w=200',
                'https://images.unsplash.com/photo-1544005313-94ddf0286df2?auto=format&fit=crop&q=80&w=200',
                null
            ];
            $photo = $photos[$w->id % 4];

            // Fetch dynamic database reviews (Requirement 1)
            $dbReviews = Review::where('worker_id', $w->id)->with('employer')->latest()->get();
            $reviews = $dbReviews->map(function ($rev) {
                return [
                    'id' => $rev->id,
                    'employer_name' => $rev->employer->name ?? 'Employer',
                    'rating' => $rev->rating,
                    'date' => $rev->created_at->format('M d, Y'),
                    'comment' => $rev->comment,
                ];
            })->toArray();

            $reviewsCount = count($reviews);
            if ($reviewsCount > 0) {
                $rating = round($dbReviews->avg('rating'), 1);
            } else {
                $rating = 0.0;
                $reviewsCount = 0;
                $reviews = [];
            }

            // Similar workers matching web view
            $simDb = Worker::with('category')
                ->where('id', '!=', $w->id)
                ->where('status', '!=', 'Hired')
                ->where('status', '!=', 'hidden')
                ->limit(3)
                ->get();

            $similarWorkers = $simDb->map(function($sw) {
                $isPending = str_contains(strtolower($sw->passport_status), 'pending');
                if ($isPending || $sw->status === 'hidden' || $sw->status === 'Hired') {
                    return null;
                }

                return [
                    'id' => $sw->id,
                    'name' => $sw->name,
                    'nationality' => $sw->nationality,
                    'rating' => 4.7,
                    'verified' => (bool)$sw->verified,
                ];
            })->filter()->values()->toArray();

            // Check if there is an existing conversation between this employer and this worker
            $conversation = \App\Models\Conversation::where('employer_id', $employer->id)
                ->where('worker_id', $w->id)
                ->first();

            $workerProfile = [
                'id' => $w->id,
                'name' => $w->name,
                'nationality' => $w->nationality,
                'photo' => $photo,
                'emirates_id_status' => $emiratesIdStatus,
                'skills' => $mappedSkills,
                'visa_status' => $visaStatus,
                'experience' => $w->experience,
                'experience_years' => 5, 
                'religion' => $w->religion,
                'languages' => $langs,
                'age' => $w->age,
                'verified' => (bool)$w->verified,
                'preferred_job_type' => $preferredJobType,
                'bio' => $w->bio,
                'rating' => $rating,
                'reviews_count' => $reviewsCount,
                'reviews' => $reviews,
                'similar_workers' => $similarWorkers,
                'conversation_id' => $conversation ? $conversation->id : null,
            ];

            return response()->json([
                'success' => true,
                'data' => [
                    'worker' => $workerProfile
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Get Worker Detail Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching the worker profile.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * GET /api/employers/shortlist
     * Retrieve the list of shortlisted workers for the authenticated employer.
     */
    public function getShortlist(Request $request)
    {
        /** @var User $employer */
        $employer = $request->attributes->get('employer');

        try {
            $page = (int)$request->input('page', 1);
            $perPage = (int)$request->input('per_page', 15);

            $shortlists = Shortlist::where('employer_id', $employer->id)
                ->with(['worker.category', 'worker.skills'])
                ->get();

            $formattedWorkers = $shortlists->map(function ($s) {
                if ($s->worker) {
                    return $this->formatWorker($s->worker);
                }
                return null;
            })->filter()->values();

            $workersArray = $formattedWorkers->toArray();
            $total = count($workersArray);
            $offset = ($page - 1) * $perPage;
            $paginatedWorkers = array_slice($workersArray, $offset, $perPage);

            return response()->json([
                'success' => true,
                'data' => [
                    'workers' => $paginatedWorkers,
                    'pagination' => [
                        'total' => $total,
                        'per_page' => $perPage,
                        'current_page' => $page,
                        'last_page' => max(1, (int)ceil($total / $perPage)),
                    ]
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Get Shortlist Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching the shortlist.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * POST /api/employers/shortlist
     * Toggle a worker's shortlist status for the authenticated employer.
     */
    public function toggleShortlist(Request $request)
    {
        /** @var User $employer */
        $employer = $request->attributes->get('employer');

        $validator = Validator::make($request->all(), [
            'worker_id' => 'required|exists:workers,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation error.',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $workerId = $request->worker_id;

            $existing = Shortlist::where('employer_id', $employer->id)
                ->where('worker_id', $workerId)
                ->first();

            if ($existing) {
                $existing->delete();
                $action = 'removed';
            } else {
                Shortlist::create([
                    'employer_id' => $employer->id,
                    'worker_id' => $workerId,
                ]);
                $action = 'added';
            }

            $shortlistedIds = Shortlist::where('employer_id', $employer->id)->pluck('worker_id')->toArray();

            return response()->json([
                'success' => true,
                'message' => "Worker successfully {$action} from shortlist.",
                'data' => [
                    'action' => $action,
                    'shortlisted_ids' => $shortlistedIds
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile API Employer Toggle Shortlist Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while toggling the shortlist.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }
}

