<?php

namespace App\Http\Controllers;

use App\Models\CallbackRequest;
use App\Models\ContactInquiry;
use App\Models\NewsletterSubscriber;
use App\Models\HomeSection;
use App\Models\PageContent;
use App\Models\PageSeo;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Throwable;

class FrontendController extends Controller
{
    public function index(): View
    {
        return $this->page('index');
    }

    public function packages(): View
    {
        return $this->page('packages');
    }

    public function candidatesProfiles(): View
    {
        return $this->page('candidates_profiles');
    }

    public function profiles(Request $request)
    {
        $locale = $this->detectLocaleFromRequest($request);
        $isArabic = $locale === 'ar';

        app()->setLocale($locale);

        $viewFile = $isArabic && view()->exists('profiles_rtl') ? 'profiles_rtl' : 'profiles';
        $profilesContent = $this->pageContent('profiles', $locale);
        $listing = $this->profilesListing($request);

        if ($request->ajax() || $request->wantsJson()) {
            return response()->json([
                'html' => view('partials.profiles_cards', [
                    'candidates' => collect($listing['candidates']),
                    'locale' => $locale,
                ])->render(),
                'hasMore' => $listing['hasMore'],
                'page' => $listing['page'],
                'perPage' => $listing['perPage'],
                'total' => $listing['total'],
                'error' => $listing['error'],
            ]);
        }

        return view($viewFile, [
            'seo' => $this->seo('profiles', $locale),
            'locale' => $locale,
            'profilesContent' => $profilesContent,
            'countryTabs' => $listing['countryTabs'],
            'filterOptions' => $listing['filterOptions'],
            'selectedCountry' => $listing['selectedCountry'],
            'selectedFilters' => $listing['filters'],
            'candidates' => $listing['candidates'],
            'hasMore' => $listing['hasMore'],
            'page' => $listing['page'],
            'perPage' => $listing['perPage'],
            'total' => $listing['total'],
        ]);
    }

    public function profileBySlug(Request $request, string $slug): View
    {
        $locale = $this->detectLocaleFromRequest($request);
        $isArabic = $locale === 'ar';

        app()->setLocale($locale);

        $allCandidates = $this->fetchProfilesFromApi('all', [
            'age' => [],
            'experience' => [],
            'language' => [],
            'religion' => [],
        ]);

        $candidate = $allCandidates->firstWhere('slug', $slug);
        abort_if(!$candidate, 404);

        $profileDetailsContent = $this->pageContent('profile_details', $locale);
        $candidateName = trim((string) data_get($candidate, 'candidate_name', 'Profile'));
        $candidateCode = trim((string) data_get($candidate, 'ref_no', ''));
        $otherProfiles = $allCandidates
            ->reject(function (array $item) use ($slug) {
                return (string) ($item['slug'] ?? '') === $slug;
            })
            ->filter(function (array $item) {
                return trim((string) ($item['candidate_name'] ?? '')) !== '';
            })
            ->sortByDesc(function (array $item) {
                return ((int) !empty($item['photo']) * 2) + ((int) !empty($item['video']));
            })
            ->take(8)
            ->values();

        $seo = $this->seo('profile_details', $locale);
        $seo['title'] = str_replace(['{name}', '{code}'], [$candidateName, $candidateCode], $seo['title'] ?? '');
        $seo['description'] = str_replace(['{name}', '{code}'], [$candidateName, $candidateCode], $seo['description'] ?? '');
        $seo['keywords'] = str_replace(['{name}', '{code}'], [$candidateName, $candidateCode], $seo['keywords'] ?? '');
        $seo['heading'] = str_replace(['{name}', '{code}'], [$candidateName, $candidateCode], $seo['heading'] ?? '');
        $seo['url'] = url()->current();

        return view($isArabic && view()->exists('profile_details_rtl') ? 'profile_details_rtl' : 'profile_details', [
            'locale' => $locale,
            'candidate' => $candidate,
            'otherProfiles' => $otherProfiles,
            'profileDetailsContent' => $profileDetailsContent,
            'seo' => $seo,
        ]);
    }

    public function services(): View
    {
        return $this->page('services');
    }

    public function fullTimeLiveIn(Request $request): View
    {
        $locale = $this->detectLocaleFromRequest($request);
        $isArabic = $locale === 'ar';

        app()->setLocale($locale);

        $viewFile = $isArabic && view()->exists('full_time_live_in_rtl') ? 'full_time_live_in_rtl' : 'full_time_live_in';

        $fullTimeLiveInContent = $this->pageContent('full_time_live_in', $locale);

        return view($viewFile, [
            'locale' => $locale,
            'fullTimeLiveInContent' => $fullTimeLiveInContent,
            'seo' => $this->seo('full_time_live_in', $locale),
        ]);
    }

    public function aboutUs(): View
    {
        return $this->page('about_us');
    }

    public function maidVisa(): View
    {
        return $this->page('maid_visa');
    }

    public function contactUs(): View
    {
        return $this->page('contact_us');
    }

    public function callbackSuccess(): View
    {
        return $this->page('callback_success');
    }

    public function termsAndConditions(): View
    {
        return $this->page('terms_and_conditions');
    }

    public function privacyPolicy(): View
    {
        return $this->page('privacy_policy');
    }

    public function callbackRequest(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'name' => ['required', 'string', 'max:120'],
            'mobile' => ['required', 'string', 'max:30'],
            'source_page' => ['nullable', 'string', 'max:255'],
        ]);

        if ($validator->fails()) {
            return back()
                ->withErrors($validator)
                ->withInput()
                ->with('open_callback_modal', true);
        }

        $locale = $this->detectLocaleFromRequest($request);
        $successRoute = ($locale === 'ar' ? 'ar.' : '') . 'enquiry.thank.you';

        CallbackRequest::query()->create([
            'name' => $request->input('name'),
            'mobile' => $request->input('mobile'),
            'locale' => $locale,
            'source_page' => $request->input('source_page') ?: '/' . ltrim($request->path(), '/'),
            'source_url' => $request->fullUrl(),
            'ip_address' => $request->ip(),
            'user_agent' => (string) $request->userAgent(),
        ]);

        return redirect()
            ->route($successRoute)
            ->with('callback_name', $request->input('name'))
            ->with('callback_mobile', $request->input('mobile'));
    }

    public function contactInquiry(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'name' => ['nullable', 'string', 'max:120'],
            'first_name' => ['nullable', 'string', 'max:120', 'required_without:name'],
            'last_name' => ['nullable', 'string', 'max:120'],
            'mobile' => ['required', 'string', 'max:30'],
            'email' => ['nullable', 'email', 'max:190'],
            'message' => ['nullable', 'string', 'max:2000'],
            'source_page' => ['nullable', 'string', 'max:255'],
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        $locale = $this->detectLocaleFromRequest($request);
        $computedName = trim((string) $request->input('first_name') . ' ' . (string) $request->input('last_name'));
        $resolvedName = $request->input('name') ?: $computedName;

        ContactInquiry::query()->create([
            'name' => $resolvedName,
            'mobile' => $request->input('mobile'),
            'email' => $request->input('email'),
            'message' => $request->input('message'),
            'locale' => $locale,
            'source_page' => $request->input('source_page') ?: '/' . ltrim($request->path(), '/'),
            'source_url' => $request->fullUrl(),
            'ip_address' => $request->ip(),
            'user_agent' => (string) $request->userAgent(),
        ]);

        $successRoute = ($locale === 'ar' ? 'ar.' : '') . 'enquiry.thank.you';

        return redirect()
            ->route($successRoute)
            ->with('callback_name', $resolvedName)
            ->with('callback_mobile', $request->input('mobile'));
    }

    public function newsletterSubscribe(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'email' => ['required', 'email', 'max:190'],
            'source_page' => ['nullable', 'string', 'max:255'],
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        $locale = $this->detectLocaleFromRequest($request);
        $email = Str::lower(trim((string) $request->input('email')));

        $existing = NewsletterSubscriber::query()->where('email', $email)->first();

        if ($existing) {
            return back()->with('newsletter_already_subscribed', true);
        }

        NewsletterSubscriber::query()->create([
            'email' => $email,
            'locale' => $locale,
            'source_page' => $request->input('source_page') ?: '/' . ltrim($request->path(), '/'),
            'source_url' => $request->fullUrl(),
            'ip_address' => $request->ip(),
            'user_agent' => (string) $request->userAgent(),
        ]);

        return back()->with('newsletter_success', true);
    }

    protected function page(string $view): View
    {
        $locale = $this->detectLocaleFromRequest(request());
        $isArabic = $locale === 'ar';

        app()->setLocale($locale);

        $rtlView = $view . '_rtl';
        $viewFile = $isArabic && view()->exists($rtlView) ? $rtlView : $view;

        $data = [
            'seo' => $this->seo($view, $locale),
            'locale' => $locale,
        ];

        if ($view === 'candidates_profiles') {
            $data['candidatesProfilesContent'] = $this->pageContent('candidates_profiles', $locale);
        }

        if (in_array($view, ['about_us', 'contact_us', 'maid_visa', 'packages', 'index', 'terms_and_conditions', 'privacy_policy'], true)) {
            $content = $this->pageContent($view, $locale);

            if ($view === 'about_us') {
                $data['aboutUsContent'] = $content;
            } elseif ($view === 'contact_us') {
                $data['contactUsContent'] = $content;
            } elseif ($view === 'packages') {
                $data['packagesContent'] = $content;
            } elseif ($view === 'index') {
                $data['homeContent'] = $content;
                $apiSlides = $this->homeProfileSlidesFromApi($locale);
                if ($apiSlides !== []) {
                    $data['homeContent']['latest_profiles']['slides'] = $apiSlides;
                }
            } elseif ($view === 'terms_and_conditions' || $view === 'privacy_policy') {
                $data['legalPageContent'] = $content;
            } else {
                $data['maidVisaContent'] = $content;
            }
        }

        if (in_array($view, ['packages', 'maid_visa'], true)) {
            $data['homeContactUs'] = HomeSection::section('contact');
        }

        return view($viewFile, $data);
    }

    protected function pageContent(string $pageKey, string $locale): array
    {
        $record = PageContent::query()->where('page_key', $pageKey)->first();
        $defaults = PageContent::defaultsForPageKey($pageKey, $locale);
        $stored = $record ? ($record->{'data_' . $locale} ?? []) : [];

        $merged = is_array($stored)
            ? array_replace_recursive($defaults, $stored)
            : $defaults;

        if ($pageKey === 'full_time_live_in') {
            return PageContent::normalizeFullTimeLiveInMerged($merged, $defaults, is_array($stored) ? $stored : []);
        }

        return $merged;
    }

    protected function profilesListing(Request $request): array
    {
        $countryTabs = [
            ['code' => 'all', 'label' => 'All', 'flag' => 'un'],
            ['code' => 'ph', 'label' => 'Filipino', 'flag' => 'ph'],
            ['code' => 'et', 'label' => 'Ethiopian', 'flag' => 'et'],
            ['code' => 'ug', 'label' => 'Ugandan', 'flag' => 'ug'],
        ];

        $filterOptions = [
            'age' => ['18-25', '26-30', '31-35', '36-45', '46+'],
            'experience' => [
                'First Time Worker',
                'United Arab Emirates',
                'Saudi Arabia',
                'Oman',
                'Bahrain',
                'Qatar',
                'Lebanon',
                'Others',
            ],
            'language' => ['Arabic', 'English'],
            'religion' => ['Christian', 'Muslim'],
        ];

        $selectedCountry = strtolower((string) $request->input('country', 'all'));
        if (!in_array($selectedCountry, ['all', 'ph', 'et', 'ug'], true)) {
            $selectedCountry = 'all';
        }

        $filters = [
            'age' => array_values(array_unique(array_intersect((array) $request->input('age', []), $filterOptions['age']))),
            'experience' => array_values(array_unique(array_intersect((array) $request->input('experience', []), $filterOptions['experience']))),
            'language' => array_values(array_unique(array_intersect((array) $request->input('language', []), $filterOptions['language']))),
            'religion' => array_values(array_unique(array_intersect((array) $request->input('religion', []), $filterOptions['religion']))),
        ];

        $page = max(1, (int) $request->input('page', 1));
        $perPage = max(1, min(24, (int) $request->input('per_page', 12)));

        try {
            $allCandidates = $this->fetchProfilesFromApi($selectedCountry, $filters)
                ->sortByDesc(function (array $candidate) {
                    return ((int) !empty($candidate['photo']) * 2) + ((int) !empty($candidate['video']));
                })
                ->values();

            $total = $allCandidates->count();
            $paged = $allCandidates
                ->slice(($page - 1) * $perPage, $perPage)
                ->values()
                ->all();

            return [
                'countryTabs' => $countryTabs,
                'filterOptions' => $filterOptions,
                'selectedCountry' => $selectedCountry,
                'filters' => $filters,
                'page' => $page,
                'perPage' => $perPage,
                'total' => $total,
                'hasMore' => $total > ($page * $perPage),
                'candidates' => $paged,
                'error' => null,
            ];
        } catch (Throwable $e) {
            return [
                'countryTabs' => $countryTabs,
                'filterOptions' => $filterOptions,
                'selectedCountry' => $selectedCountry,
                'filters' => $filters,
                'page' => $page,
                'perPage' => $perPage,
                'total' => 0,
                'hasMore' => false,
                'candidates' => [],
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Build homepage “latest profiles” carousel slides from the same API used on /profiles.
     * Returns [] when the API is unavailable or returns no candidates (CMS slides are kept).
     *
     * @return array<int, array<int, array<string, mixed>>>
     */
    protected function homeProfileSlidesFromApi(string $locale): array
    {
        $filters = [
            'age' => [],
            'experience' => [],
            'language' => [],
            'religion' => [],
        ];

        try {
            $candidates = $this->fetchProfilesFromApi('all', $filters)
                ->sortByDesc(function (array $candidate) {
                    return ((int) ! empty($candidate['photo']) * 2) + ((int) ! empty($candidate['video']));
                })
                ->values();
        } catch (Throwable $e) {
            return [];
        }

        if ($candidates->isEmpty()) {
            return [];
        }

        $profilesUi = $this->pageContent('profiles', $locale);

        return $candidates
            ->take(12)
            ->map(fn (array $c) => $this->mapCandidateToHomeProfileCard($c, $profilesUi, $locale))
            ->chunk(3)
            ->values()
            ->map(static fn ($chunk) => $chunk->values()->all())
            ->all();
    }

    /**
     * Map an API candidate to the shape used by {@see resources/views/index.blade.php} maid-profile-card.
     *
     * @param  array<string, mixed>  $candidate
     * @param  array<string, mixed>  $profilesUi
     * @return array<string, mixed>
     */
    protected function mapCandidateToHomeProfileCard(array $candidate, array $profilesUi, string $locale): array
    {
        $name = trim((string) ($candidate['candidate_name'] ?? ''));
        $slug = trim((string) ($candidate['slug'] ?? ''));
        $code = trim((string) ($candidate['ref_no'] ?? ''));
        $image = trim((string) ($candidate['photo'] ?? ''));
        $video = trim((string) ($candidate['video'] ?? ''));
        $cv = trim((string) ($candidate['cv_url'] ?? ''));
        $country = trim((string) ($candidate['nationality'] ?? ''));
        $religion = trim((string) ($candidate['religion'] ?? ''));
        $languages = array_values(array_filter((array) ($candidate['languages'] ?? [])));
        $maritalStatus = trim((string) ($candidate['marital_status'] ?? ''));
        $children = (int) ($candidate['children_count'] ?? 0);
        $experienceCountries = array_values(array_filter((array) ($candidate['experience_countries'] ?? [])));
        $experienceLabel = trim((string) ($candidate['experience_bucket'] ?? ''));
        $experienceYears = (int) ($candidate['experience_years'] ?? 0);
        $expText = $experienceLabel !== '' ? $experienceLabel : ($experienceYears > 0 ? $experienceYears.' Years' : 'First Time Worker');
        $salary = $candidate['salary'] ?? null;
        $salaryText = is_numeric($salary) ? number_format((int) $salary).' AED / '.($locale === 'ar' ? 'شهر' : 'month') : '';

        $imageUrl = $image !== '' ? $image : 'https://images.unsplash.com/photo-1544717305-2782549b5136?auto=format&fit=crop&w=800&q=80';

        $hireHref = $slug !== ''
            ? ($locale === 'ar' ? route('ar.profiles.show', ['slug' => $slug]) : route('profiles.show', ['slug' => $slug]))
            : ($locale === 'ar' ? route('ar.contact.us') : route('contact.us'));

        $cvHref = $cv !== '' ? $cv : $hireHref;
        $cvText = (string) data_get($profilesUi, 'labels.view_cv', 'View CV');

        $details = [];
        if ($country !== '') {
            $details[] = '<strong>'.e(data_get($profilesUi, 'labels.nationality', 'Nationality')).':</strong> '.e($country);
        }
        $details[] = '<strong>'.e(data_get($profilesUi, 'labels.religion', 'Religion')).':</strong> '.e($religion !== '' ? $religion : '-')
            .', <strong>'.e(data_get($profilesUi, 'labels.speaks', 'Speaks')).':</strong> '.e(count($languages) ? implode(', ', $languages) : '-');
        $details[] = '<strong>'.e(data_get($profilesUi, 'labels.marital_status', 'Marital Status')).':</strong> '.e($maritalStatus !== '' ? $maritalStatus : '-')
            .', <strong>'.e(data_get($profilesUi, 'labels.children', 'Children')).':</strong> '.e((string) $children);
        $details[] = '<strong>'.e(data_get($profilesUi, 'labels.experience', 'Experience')).':</strong> '.e($expText);
        if (count($experienceCountries)) {
            $details[] = '<strong>'.e(data_get($profilesUi, 'labels.experience_countries', 'Experience in Countries')).':</strong> '.e(implode(', ', $experienceCountries));
        }
        if ($salaryText !== '') {
            $details[] = '<strong>'.e(data_get($profilesUi, 'labels.salary', 'Salary')).':</strong> '.e($salaryText);
        }

        return [
            'image' => $imageUrl,
            'image_alt' => $name,
            'video_href' => $video,
            'play_aria' => (string) data_get($profilesUi, 'labels.play_aria', 'Play candidate video'),
            'code' => $code,
            'name' => $name,
            'slug' => $slug,
            'share_aria' => (string) data_get($profilesUi, 'labels.share_aria', 'Share profile'),
            'details' => $details,
            'cv_href' => $cvHref,
            'cv_text' => $cvText,
            'hire_href' => $hireHref,
            'hire_route' => 'contact.us',
            'hire_text' => (string) data_get($profilesUi, 'labels.hire_me', 'Hire Me'),
            'favorite_aria' => (string) data_get($profilesUi, 'labels.save_aria', 'Save profile'),
        ];
    }

    protected function fetchProfilesFromApi(string $selectedCountry, array $filters): Collection
    {
        $nationalityIds = match ($selectedCountry) {
            'ph' => [3],
            'et' => [1],
            'ug' => [2],
            default => [3, 1, 2],
        };

        return collect()
            ->merge($this->fetchProfilesBucket('outside', 'personal', $nationalityIds, $filters))
            ->merge($this->fetchProfilesBucket('inside', 'personal', $nationalityIds, $filters))
            ->merge($this->fetchProfilesBucket('inside', 'company', $nationalityIds, $filters))
            ->unique('uid')
            ->filter(function (array $candidate) use ($selectedCountry, $filters) {
                if ($selectedCountry !== 'all' && ($candidate['country_code'] ?? '') !== $selectedCountry) {
                    return false;
                }

                if ($filters['age'] && !in_array($candidate['age_group'] ?? '', $filters['age'], true)) {
                    return false;
                }

                if ($filters['religion'] && !in_array($candidate['religion'] ?? '', $filters['religion'], true)) {
                    return false;
                }

                if ($filters['language']) {
                    $candidateLanguages = array_map('strtolower', (array) ($candidate['languages'] ?? []));
                    $selectedLanguages = array_map('strtolower', $filters['language']);

                    if (!count(array_intersect($candidateLanguages, $selectedLanguages))) {
                        return false;
                    }
                }

                if (!$this->matchesExperienceSelection($candidate, $filters['experience'])) {
                    return false;
                }

                return true;
            })
            ->values();
    }

    protected function fetchProfilesBucket(string $category, string $sponsorship, array $nationalityIds, array $filters): Collection
    {
        $url = trim((string) config('services.outside_candidates.url'));
        $token = trim((string) config('services.outside_candidates.token'));

        if ($url === '' || $token === '') {
            return collect();
        }

        $page = 1;
        $perPage = 100;
        $guard = 0;
        $items = collect();

        do {
            $query = [
                'api_token' => $token,
                'category' => $category,
                'sponsorship' => $sponsorship,
                'page' => $page,
                'per_page' => $perPage,
            ];

            foreach ($nationalityIds as $i => $nationalityId) {
                $query["nationality[$i]"] = $nationalityId;
            }

            foreach ($filters['age'] as $i => $range) {
                if (preg_match('/^(\d+)-(\d+)$/', $range, $matches)) {
                    $query["ages[$i][min]"] = (int) $matches[1];
                    $query["ages[$i][max]"] = (int) $matches[2];
                } elseif ($range === '46+') {
                    $query["ages[$i][min]"] = 46;
                    $query["ages[$i][max]"] = 100;
                }
            }

            foreach ($filters['language'] as $i => $language) {
                $query["language[$i]"] = $language;
            }

            foreach ($filters['religion'] as $i => $religion) {
                $query["religion[$i]"] = $religion;
            }

            foreach ($filters['experience'] as $i => $experience) {
                $query["experience[$i]"] = $experience;
            }

            try {
                $response = Http::retry(2, 200)
                    ->timeout(20)
                    ->acceptJson()
                    ->get($url, $query);
            } catch (ConnectionException $e) {
                break;
            }

            if ($response->failed()) {
                break;
            }

            $payload = $response->json();

            if (!is_array($payload)) {
                break;
            }

            $pageItems = collect(data_get($payload, 'data', []))
                ->map(function ($row) use ($category, $sponsorship) {
                    return $this->normalizeProfileCandidate($row, $category, $sponsorship);
                })
                ->filter(function (array $candidate) {
                    return in_array($candidate['country_code'] ?? '', ['ph', 'et', 'ug'], true);
                });

            $items = $items->merge($pageItems);

            $page++;
            $guard++;
            $hasNext = !empty(data_get($payload, 'links.next'));
        } while ($hasNext && $guard < 20);

        return $items->values();
    }

    protected function normalizeProfileCandidate($row, string $category, string $sponsorship): array
    {
        $data = is_object($row) ? (array) $row : (array) $row;

        $nationalityValue = $data['nationality'] ?? null;
        $nationalityId = $this->profileEntityId($nationalityValue);
        $nationality = $this->normalizeProfileNationality(
            $this->profileLocalizedValue($nationalityValue, ['name', 'country', 'nationality'], ['name_ar', 'arabic', 'arabic_name']),
            $nationalityId
        );
        $countryCode = $this->profileCountryCode($nationality, $nationalityId);

        $candidateName = trim((string) ($data['candidate_name'] ?? ($data['name'] ?? '')));
        $referenceNo = trim((string) ($data['reference_no'] ?? ''));
        $refNo = trim((string) ($data['ref_no'] ?? $referenceNo));

        $religion = $this->normalizeProfileReligion((string) ($data['religion'] ?? ''));
        $languages = $this->profileLanguages($data);
        $maritalStatus = $this->profileLocalizedValue(
            $data['marital_status'] ?? null,
            ['status_name', 'name'],
            ['status_name_ar', 'name_ar']
        );

        $childrenCount = (int) ($data['number_of_children'] ?? ($data['children_count'] ?? 0));
        $age = is_numeric($data['age'] ?? null) ? (int) $data['age'] : null;
        $ageGroup = $this->profileAgeGroup($age);

        $experiences = collect($data['experiences'] ?? [])
            ->map(function ($experience) {
                $item = is_object($experience) ? (array) $experience : (array) $experience;

                return [
                    'country' => $this->normalizeProfileExperienceCountry((string) ($item['country'] ?? '')),
                    'experience_years' => is_numeric($item['experience_years'] ?? null) ? (int) $item['experience_years'] : 0,
                    'experience_months' => is_numeric($item['experience_months'] ?? null) ? (int) $item['experience_months'] : 0,
                ];
            })
            ->filter(function (array $item) {
                return $item['country'] !== '' || $item['experience_years'] > 0 || $item['experience_months'] > 0;
            })
            ->values()
            ->all();

        $experienceYears = $this->profileExperienceYears($data, $category, collect($experiences));
        $experienceBucket = $this->profileExperienceBucket($experienceYears);
        $experienceCountries = collect($experiences)->pluck('country')->filter()->unique()->values()->all();

        $rawSalary = $data['salary'] ?? null;
        $salary = null;
        if (is_numeric($rawSalary)) {
            $salary = (float) $rawSalary;
            if ($category === 'outside' && $countryCode === 'ph') {
                $salary = round($salary * 3.6);
            }
            $salary = max(1200, (int) round($salary));
        }

        $attachments = $data['attachments'] ?? [];
        $photoPath = $this->profilePickAttachment($attachments, 'Passport Size Photo');
        $videoPath = $this->profilePickAttachment($attachments, 'Video');
        $foreignPartner = trim((string) ($data['foreign_partner'] ?? ''));

        $uid = $category . '-' . $sponsorship . '-' . ($data['id'] ?? '0') . '-' . ($refNo !== '' ? $refNo : Str::slug($candidateName));
        $slugBase = trim(($candidateName !== '' ? $candidateName : 'candidate') . ($refNo !== '' ? '-' . $refNo : ''));
        $slug = Str::slug($slugBase);

        return [
            'uid' => trim(preg_replace('/[^A-Za-z0-9\-_]+/', '-', $uid), '-'),
            'id' => $data['id'] ?? null,
            'slug' => $slug !== '' ? $slug : 'candidate-' . ($data['id'] ?? '0'),
            'ref_no' => $refNo,
            'candidate_name' => $candidateName,
            'nationality' => $nationality,
            'country_code' => $countryCode,
            'religion' => $religion,
            'languages' => $languages,
            'marital_status' => $maritalStatus,
            'children_count' => $childrenCount,
            'age' => $age,
            'age_group' => $ageGroup,
            'experience_years' => $experienceYears,
            'experience_bucket' => $experienceBucket,
            'experience_countries' => $experienceCountries,
            'salary' => $salary,
            'photo' => $this->profileResolveMediaUrl($photoPath, $category, $foreignPartner),
            'video' => $this->profileResolveMediaUrl($videoPath, $category, $foreignPartner),
            'cv_url' => $this->profileCvUrl($referenceNo !== '' ? $referenceNo : $refNo, $category, $sponsorship),
            'experiences' => $experiences,
        ];
    }

    protected function matchesExperienceSelection(array $candidate, array $selected): bool
    {
        if (!$selected) {
            return true;
        }

        $countries = array_values(array_unique((array) ($candidate['experience_countries'] ?? [])));
        $years = (int) ($candidate['experience_years'] ?? 0);
        $common = [
            'United Arab Emirates',
            'Saudi Arabia',
            'Oman',
            'Bahrain',
            'Qatar',
            'Lebanon',
        ];

        foreach ($selected as $value) {
            if ($value === 'First Time Worker') {
                if ($years <= 0 || !$countries) {
                    return true;
                }
                continue;
            }

            if ($value === 'Others') {
                if ($years > 0 && !count(array_intersect($countries, $common))) {
                    return true;
                }
                continue;
            }

            if (in_array($value, $countries, true)) {
                return true;
            }
        }

        return false;
    }

    protected function profileLocalizedValue($value, array $enKeys, array $arKeys): string
    {
        if ($value === null) {
            return '';
        }

        if (is_string($value)) {
            return trim($value);
        }

        if (is_object($value)) {
            $value = (array) $value;
        }

        if (!is_array($value)) {
            return trim((string) $value);
        }

        $locale = app()->getLocale();
        $keys = $locale === 'ar' ? array_merge($arKeys, $enKeys) : array_merge($enKeys, $arKeys);

        foreach ($keys as $key) {
            if (isset($value[$key]) && is_string($value[$key]) && trim($value[$key]) !== '') {
                return trim((string) $value[$key]);
            }
        }

        return '';
    }

    protected function profileEntityId($value): ?int
    {
        if (is_array($value) && isset($value['id']) && is_numeric($value['id'])) {
            return (int) $value['id'];
        }

        if (is_object($value) && isset($value->id) && is_numeric($value->id)) {
            return (int) $value->id;
        }

        return null;
    }

    protected function normalizeProfileNationality(string $name, ?int $id): string
    {
        if ($id === 3) {
            return 'Philippines';
        }

        if ($id === 1) {
            return 'Ethiopia';
        }

        if ($id === 2) {
            return 'Uganda';
        }

        return match (Str::lower(trim($name))) {
            'filipino', 'philippine', 'philippines', 'philpine' => 'Philippines',
            'ethiopia', 'ethiopian' => 'Ethiopia',
            'uganda', 'ugandan' => 'Uganda',
            default => trim($name),
        };
    }

    protected function profileCountryCode(string $name, ?int $id): string
    {
        if ($id === 3) {
            return 'ph';
        }

        if ($id === 1) {
            return 'et';
        }

        if ($id === 2) {
            return 'ug';
        }

        return match (Str::lower(trim($name))) {
            'philippines', 'filipino', 'philippine', 'philpine' => 'ph',
            'ethiopia', 'ethiopian' => 'et',
            'uganda', 'ugandan' => 'ug',
            default => '',
        };
    }

    protected function normalizeProfileReligion(string $religion): string
    {
        $value = Str::lower(trim($religion));

        if ($value === '') {
            return '';
        }

        if (Str::contains($value, 'christ')) {
            return 'Christian';
        }

        if (Str::contains($value, 'muslim') || Str::contains($value, 'islam')) {
            return 'Muslim';
        }

        return Str::title($religion);
    }

    protected function profileLanguages(array $row): array
    {
        $languages = [];

        if (!empty($row['english_skills'])) {
            $languages[] = 'English';
        }

        if (!empty($row['arabic_skills'])) {
            $languages[] = 'Arabic';
        }

        $source = $row['languages'] ?? null;

        if (is_string($source) && trim($source) !== '') {
            foreach (preg_split('/[,|]/', $source) as $language) {
                $value = Str::title(trim((string) $language));
                if ($value !== '') {
                    $languages[] = $value;
                }
            }
        }

        if (is_array($source)) {
            foreach ($source as $language) {
                if (is_object($language)) {
                    $language = (array) $language;
                }

                if (is_array($language)) {
                    $value = trim((string) ($language['name'] ?? ($language['language'] ?? '')));
                } else {
                    $value = trim((string) $language);
                }

                if ($value !== '') {
                    $languages[] = Str::title($value);
                }
            }
        }

        return collect($languages)->filter()->unique()->values()->all();
    }

    protected function profileAgeGroup(?int $age): string
    {
        if (is_null($age) || $age <= 0) {
            return '';
        }

        return match (true) {
            $age >= 18 && $age <= 25 => '18-25',
            $age >= 26 && $age <= 30 => '26-30',
            $age >= 31 && $age <= 35 => '31-35',
            $age >= 36 && $age <= 45 => '36-45',
            $age >= 46 => '46+',
            default => '',
        };
    }

    protected function normalizeProfileExperienceCountry(string $country): string
    {
        return match (Str::lower(trim($country))) {
            'uae', 'u.a.e', 'united arab emirates', 'united arab emirate' => 'United Arab Emirates',
            'ksa', 'saudi', 'saudi arabia' => 'Saudi Arabia',
            'oman' => 'Oman',
            'bahrain' => 'Bahrain',
            'qatar' => 'Qatar',
            'lebanon' => 'Lebanon',
            default => Str::title(trim($country)),
        };
    }

    protected function profileExperienceYears(array $row, string $category, Collection $experiences): int
    {
        if ($category === 'inside' && is_numeric($row['experience_years'] ?? null)) {
            return max(0, min(10, (int) $row['experience_years']));
        }

        return max(0, min(10, (int) $experiences->sum('experience_years')));
    }

    protected function profileExperienceBucket(int $years): string
    {
        if ($years <= 0) {
            return 'First Time Worker';
        }

        if ($years >= 10) {
            return '10+ Years';
        }

        if ($years === 1) {
            return '1 Year';
        }

        return $years . ' Years';
    }

    protected function profilePickAttachment($attachments, string $wantedType): string
    {
        $wanted = Str::lower(trim($wantedType));
        $items = is_array($attachments) ? $attachments : (is_object($attachments) ? (array) $attachments : []);

        foreach ($items as $item) {
            if (is_string($item)) {
                $value = trim($item);
                if ($value !== '' && $wanted === 'video') {
                    return $value;
                }
                continue;
            }

            if (is_object($item)) {
                $item = (array) $item;
            }

            if (!is_array($item)) {
                continue;
            }

            $type = Str::lower(trim((string) ($item['attachment_type'] ?? ($item['type'] ?? ''))));
            $value = trim((string) ($item['attachment_file'] ?? ($item['file'] ?? ($item['url'] ?? ''))));

            if ($type === $wanted && $value !== '') {
                return $value;
            }
        }

        return '';
    }

    protected function profileResolveMediaUrl(string $value, string $category, string $foreignPartner = ''): string
    {
        $value = trim($value);

        if ($value === '' || $value === '#') {
            return '';
        }

        if (Str::startsWith($value, ['http://', 'https://', '//'])) {
            return $value;
        }

        if ($category === 'inside') {
            $path = str_replace('\\', '/', $value);
            $path = ltrim($path, '/');
            $path = preg_replace('#^storage/app/public/#i', 'storage/', $path);
            $path = preg_replace('#^(app/public|public)/#i', '', $path);

            if (!Str::startsWith($path, 'storage/')) {
                $path = 'storage/' . ltrim($path, '/');
            }

            return 'https://tadbeeralebdaa.onesourceerp.com/' . ltrim($path, '/');
        }

        $base = strtolower(strtok(trim($foreignPartner), ' ')) ?: 'tadbeeralebdaa';
        $path = str_replace('\\', '/', $value);
        $path = ltrim($path, '/');
        $path = preg_replace('#^storage/app/public/#i', '', $path);
        $path = preg_replace('#^storage/#i', '', $path);
        $path = preg_replace('#^(app/public|public)/#i', '', $path);

        return 'https://' . $base . '.onesourceerp.com/storage/app/public/' . ltrim($path, '/');
    }

    protected function profileCvUrl(string $referenceNo, string $category, string $sponsorship): string
    {
        $referenceNo = trim($referenceNo);

        if ($referenceNo === '') {
            return '';
        }

        $type = 'candidate';

        if ($category === 'inside') {
            $type = $sponsorship === 'company' ? 'employee' : 'package';
        }

        return 'https://tadbeeralebdaa.onesourceerp.com/' . $type . '/' . $referenceNo . '/cv';
    }

    protected function seo(string $page, string $locale): array
    {
        $siteName = config('app.name', 'One Source ERP');
        $baseUrl = rtrim(config('app.url'), '/');
        $isArabic = $locale === 'ar';

        $pages = [
            'index' => [
                'en' => [
                    'title' => 'Trusted Domestic Worker Recruitment Services in UAE',
                    'description' => 'Find reliable domestic worker recruitment services in the UAE.',
                    'keywords' => 'domestic worker UAE, maid services UAE',
                    'heading' => 'Trusted Domestic Worker Recruitment Services in UAE',
                ],
                'ar' => [
                    'title' => 'خدمات موثوقة لتوظيف العمالة المنزلية في الإمارات',
                    'description' => 'اكتشف خدمات موثوقة لتوظيف العمالة المنزلية في الإمارات.',
                    'keywords' => 'العمالة المنزلية في الإمارات, خادمات في الإمارات',
                    'heading' => 'خدمات موثوقة لتوظيف العمالة المنزلية في الإمارات',
                ],
            ],
            'packages' => [
                'en' => [
                    'title' => 'Recruitment Packages for Domestic Workers in UAE',
                    'description' => 'Compare domestic worker recruitment packages in the UAE.',
                    'keywords' => 'maid packages UAE, domestic worker packages',
                    'heading' => 'Recruitment Packages',
                ],
                'ar' => [
                    'title' => 'باقات توظيف العمالة المنزلية في الإمارات',
                    'description' => 'قارن بين باقات توظيف العمالة المنزلية في الإمارات.',
                    'keywords' => 'باقات خادمات الإمارات, باقات العمالة المنزلية',
                    'heading' => 'باقات التوظيف',
                ],
            ],
            'candidates_profiles' => [
                'en' => [
                    'title' => 'Domestic Worker Candidate Profiles in UAE',
                    'description' => 'Browse domestic worker candidate profiles in the UAE.',
                    'keywords' => 'maid profiles UAE, nanny profiles UAE',
                    'heading' => 'Candidate Profiles',
                ],
                'ar' => [
                    'title' => 'ملفات مرشحي العمالة المنزلية في الإمارات',
                    'description' => 'تصفح ملفات مرشحي العمالة المنزلية في الإمارات.',
                    'keywords' => 'ملفات خادمات الإمارات, مرشحي العمالة المنزلية',
                    'heading' => 'ملفات المرشحين',
                ],
            ],
            'profiles' => [
                'en' => [
                    'title' => 'Candidate Profiles | Hire Maid in Dubai',
                    'description' => 'Browse live-in maid candidate profiles, filter by nationality and experience, and watch introduction videos.',
                    'keywords' => 'maid profiles Dubai, candidate profiles UAE, hire maid Dubai',
                    'heading' => 'Candidate Profiles',
                    'robots' => 'noindex,nofollow',
                ],
                'ar' => [
                    'title' => 'ملفات المرشحين | توظيف خادمة في دبي',
                    'description' => 'تصفح ملفات مرشحي العمالة المنزلية، مع تصفية حسب الجنسية والخبرة ومقاطع تعريفية.',
                    'keywords' => 'ملفات خادمات دبي, مرشحون الإمارات',
                    'heading' => 'ملفات المرشحين',
                    'robots' => 'noindex,nofollow',
                ],
            ],
            'profile_details' => [
                'en' => [
                    'title' => '{name} Profile | The Maids',
                    'description' => 'Details for {name} ({code}) including nationality, experience, and expected salary.',
                    'keywords' => 'maid profile, {name}, {code}',
                    'heading' => '{name} | The Maids',
                ],
                'ar' => [
                    'title' => 'ملف {name} ({code}) | The Maids',
                    'description' => 'تفاصيل ملف {name} ({code}) تشمل الجنسية والخبرة والراتب المتوقع.',
                    'keywords' => 'ملف خادمة, {name}, {code}',
                    'heading' => '{name} | The Maids',
                ],
            ],
            'services' => [
                'en' => [
                    'title' => 'Domestic Worker Services in UAE',
                    'description' => 'Explore complete domestic worker services in the UAE.',
                    'keywords' => 'domestic worker services UAE, maid recruitment services',
                    'heading' => 'Our Services',
                ],
                'ar' => [
                    'title' => 'خدمات العمالة المنزلية في الإمارات',
                    'description' => 'اكتشف خدمات العمالة المنزلية المتكاملة في الإمارات.',
                    'keywords' => 'خدمات العمالة المنزلية, خدمات خادمات الإمارات',
                    'heading' => 'خدماتنا',
                ],
            ],
            'full_time_live_in' => [
                'en' => [
                    'title' => 'Hire Full Time Live-In Maid in Dubai | The Maids',
                    'description' => 'Choose between TADBEER or Family sponsorship for full-time live-in maids. Compare pricing, features, and get started quickly.',
                    'keywords' => 'full time live in maid Dubai, TADBEER sponsorship, family sponsorship maid UAE',
                    'heading' => 'Full Time Live-In Packages',
                ],
                'ar' => [
                    'title' => 'توظيف خادمة مقيمة بدوام كامل في دبي | The Maids',
                    'description' => 'اختر بين رعاية تدبير أو الرعاية العائلية للخادمة المقيمة بدوام كامل مع مقارنة واضحة للأسعار والمزايا.',
                    'keywords' => 'خادمة مقيمة دبي, رعاية تدبير, رعاية عائلية',
                    'heading' => 'باقات الخادمة المقيمة بدوام كامل',
                ],
            ],
            'about_us' => [
                'en' => [
                    'title' => 'About Us | Domestic Worker Recruitment in UAE',
                    'description' => 'Learn more about our domestic worker recruitment company in the UAE.',
                    'keywords' => 'about maid agency UAE, domestic worker recruitment company',
                    'heading' => 'About Us',
                ],
                'ar' => [
                    'title' => 'من نحن | توظيف العمالة المنزلية في الإمارات',
                    'description' => 'تعرّف أكثر على شركتنا المتخصصة في توظيف العمالة المنزلية في الإمارات.',
                    'keywords' => 'من نحن خادمات الإمارات, وكالة خادمات الإمارات',
                    'heading' => 'من نحن',
                ],
            ],
            'maid_visa' => [
                'en' => [
                    'title' => 'Maid Visa Assistance in UAE',
                    'description' => 'Get maid visa assistance in the UAE.',
                    'keywords' => 'maid visa UAE, domestic worker visa UAE',
                    'heading' => 'Maid Visa Assistance',
                ],
                'ar' => [
                    'title' => 'خدمات تأشيرة الخادمة في الإمارات',
                    'description' => 'احصل على خدمات مساعدة في تأشيرة الخادمة في الإمارات.',
                    'keywords' => 'تأشيرة خادمة الإمارات, تأشيرة عمالة منزلية',
                    'heading' => 'خدمات تأشيرة الخادمة',
                ],
            ],
            'contact_us' => [
                'en' => [
                    'title' => 'Contact Us for Domestic Worker Services in UAE',
                    'description' => 'Contact us for domestic worker recruitment services in the UAE.',
                    'keywords' => 'contact maid agency UAE, contact domestic worker services',
                    'heading' => 'Contact Us',
                ],
                'ar' => [
                    'title' => 'تواصل معنا لخدمات العمالة المنزلية في الإمارات',
                    'description' => 'تواصل معنا للحصول على خدمات توظيف العمالة المنزلية في الإمارات.',
                    'keywords' => 'تواصل معنا خادمات الإمارات, تواصل وكالة خادمات',
                    'heading' => 'تواصل معنا',
                ],
            ],
            'callback_success' => [
                'en' => [
                    'title' => 'Callback Request Received | Domestic Worker Services UAE',
                    'description' => 'Your callback request has been received. Our team will contact you shortly.',
                    'keywords' => 'callback request UAE, maid service callback, contact support',
                    'heading' => 'Callback Request Received',
                    'robots' => 'noindex,follow',
                ],
                'ar' => [
                    'title' => 'تم استلام طلب الاتصال | خدمات العمالة المنزلية في الإمارات',
                    'description' => 'تم استلام طلب الاتصال الخاص بك. سيتواصل فريقنا معك قريباً.',
                    'keywords' => 'طلب اتصال الإمارات, دعم خدمات الخادمات, تواصل',
                    'heading' => 'تم استلام طلب الاتصال',
                    'robots' => 'noindex,follow',
                ],
            ],
            'terms_and_conditions' => [
                'en' => [
                    'title' => 'Terms & Conditions | Alebdaa Workers Employment Services',
                    'description' => 'Terms for using maids-dxb.com and domestic staffing services from Alebdaa Workers Employment Services Center in the UAE.',
                    'keywords' => 'terms and conditions, maids-dxb, maid agency UAE, domestic worker services',
                    'heading' => 'Terms & Conditions',
                ],
                'ar' => [
                    'title' => 'الشروط والأحكام | مركز الإبداع لخدمات توظيف العمالة المساعدة',
                    'description' => 'اطّلع على الشروط والأحكام الخاصة باستخدام خدمات الاستقدام والعمالة المنزلية في الإمارات.',
                    'keywords' => 'شروط وأحكام, وكالة خادمات الإمارات, شروط الخدمة',
                    'heading' => 'الشروط والأحكام',
                ],
            ],
            'privacy_policy' => [
                'en' => [
                    'title' => 'Privacy Policy | Alebdaa Workers Employment Services',
                    'description' => 'How we collect, use, and protect your personal information when you use our website and services in the UAE.',
                    'keywords' => 'privacy policy, data protection UAE, maid agency privacy',
                    'heading' => 'Privacy Policy',
                ],
                'ar' => [
                    'title' => 'سياسة الخصوصية | مركز الإبداع لخدمات توظيف العمالة المساعدة',
                    'description' => 'كيفية جمعنا واستخدامنا وحمايتنا لمعلوماتك الشخصية عند استخدامك لموقعنا وخدماتنا في الإمارات.',
                    'keywords' => 'سياسة الخصوصية, حماية البيانات الإمارات, خصوصية وكالة خادمات',
                    'heading' => 'سياسة الخصوصية',
                ],
            ],
        ];

        $data = $pages[$page][$isArabic ? 'ar' : 'en'];
        $path = request()->path();
        $canonical = $path === '/' ? $baseUrl : $baseUrl . '/' . ltrim($path, '/');
        $twitterCard = 'summary_large_image';

        $pageSeo = PageSeo::query()->where('page_key', $page)->first();

        if ($pageSeo) {
            $lang = $isArabic ? 'ar' : 'en';

            foreach (['title', 'description', 'keywords', 'heading'] as $field) {
                $value = $pageSeo->{"{$field}_{$lang}"} ?? null;

                if (is_string($value) && $value !== '') {
                    $data[$field] = $value;
                }
            }

            if (filled($pageSeo->robots)) {
                $data['robots'] = $pageSeo->robots;
            }

            if (filled($pageSeo->twitter_card)) {
                $twitterCard = $pageSeo->twitter_card;
            }

            if (filled($pageSeo->canonical_url)) {
                $canonical = $pageSeo->canonical_url;
            }
        }

        return [
            'title' => $data['title'],
            'description' => $data['description'],
            'keywords' => $data['keywords'],
            'heading' => $data['heading'],
            'site_name' => $siteName,
            'url' => $canonical,
            'image' => asset('project/assets/images/seo-banner.jpg'),
            'type' => 'website',
            'robots' => $data['robots'] ?? 'index,follow',
            'locale' => $isArabic ? 'ar_AE' : 'en_US',
            'alternate_locale' => $isArabic ? 'en_US' : 'ar_AE',
            'twitter_card' => $twitterCard,
        ];
    }

    protected function detectLocaleFromRequest(Request $request): string
    {
        if ($request->routeIs('ar.*')) {
            return 'ar';
        }

        if ($request->segment(1) === 'ar') {
            return 'ar';
        }

        $locale = app()->getLocale();

        return in_array($locale, ['en', 'ar'], true) ? $locale : 'en';
    }
}
