<?php

namespace App\Http\Controllers\Employer;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Inertia\Inertia;
use App\Models\User;
use App\Models\Worker;
use App\Models\WorkerCategory;
use App\Models\Shortlist;
use App\Models\JobOffer;
use App\Models\Review;
use App\Models\ProfileView;

class WorkerController extends Controller
{
    private function resolveCurrentUser()
    {
        $sess = session('user');
        $sessId = is_array($sess) ? ($sess['id'] ?? null) : ($sess->id ?? null);

        if (!$sessId) {
            $user = User::where('role', 'employer')->first();
            if ($user) {
                session([
                    'user' => (object) [
                        'id' => $user->id,
                        'name' => $user->name,
                        'email' => $user->email,
                        'role' => 'employer',
                        'subscription_status' => $user->subscription_status ?? 'active',
                    ]
                ]);
                return $user;
            }
        } else {
            return User::find($sessId);
        }

        return null;
    }

    public function index(Request $request)
    {
        $user = $this->resolveCurrentUser();
        $employerId = $user ? $user->id : 2;

        $dbWorkers = Worker::with(['category', 'skills', 'documents'])
            ->where('status', '!=', 'Hired')
            ->where('status', '!=', 'hidden')
            ->get();

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

            // Map languages from database comma-separated string
            $langs = $w->language ? array_map('trim', explode(',', $w->language)) : ['English'];

            // 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 (now dynamic passport status)
            $emiratesIdStatus = $w->emirates_id_status;

            // Map skills dynamically from database
            $mappedSkills = $w->skills->pluck('name')->toArray();
            if (empty($mappedSkills)) {
                $mappedSkills = ['cooking', 'cleaning'];
            }

            // 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 // Test optional photo placeholder
            ];
            $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,
                'phone' => $w->phone,
                'gender' => $w->gender ?? 'Female',
                'nationality' => $w->nationality,
                'photo' => $photo,
                'emirates_id_status' => $emiratesIdStatus,
                'passport_status' => $w->passport_status,
                'category' => $w->category ? $w->category->name : 'Domestic Worker',
                'skills' => $mappedSkills,
                'visa_status' => $visaStatus,
                'experience' => $w->experience,
                'salary' => (int) $w->salary,
                'religion' => $w->religion,
                'languages' => $langs,
                'age' => $w->age,
                'verified' => (bool) $w->verified,
                'preferred_job_type' => $preferredJobType,
                'live_in_out' => $w->live_in_out ?? 'Live-in',
                'bio' => $w->bio,
                'rating' => $rating,
                'reviews_count' => $reviewsCount,
                'preferred_location' => $w->preferred_location,
                'in_country' => (bool) $w->in_country,
            ];
        })->filter()->values()->toArray();

        // Apply request filters: preferred_location, job_type, live_in_out, nationality, in_country, visa_status
        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);
            
            $workers = array_values(array_filter($workers, 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;
            }));
        }

        $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);

            $workers = array_values(array_filter($workers, 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;
            }));
        }

        $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);

            $workers = array_values(array_filter($workers, 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;
            }));
        }

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

            $workers = array_values(array_filter($workers, 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->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) {
                    $workers = array_values(array_filter($workers, 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) {
                    $workers = array_values(array_filter($workers, function ($c) use ($isOutCountry) {
                        return isset($c['in_country']) && (bool)$c['in_country'] !== $isOutCountry;
                    }));
                }
            }
        }

        $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);

            $workers = array_values(array_filter($workers, 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;
            }));
        }


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

        $dbCategories = WorkerCategory::pluck('name')->toArray();
        $dbNationalities = Worker::distinct()->pluck('nationality')->toArray();

        $filtersMetadata = [
            'categories' => array_merge(['All Categories'], $dbCategories),
            'nationalities' => array_merge(['All Nationalities'], $dbNationalities),
            'experienceLevels' => ['All Experience', '1-2 Years', '3-5 Years', '5+ Years'],
            'religions' => ['All Religions', 'Christian', 'Muslim', 'Hindu', 'Buddhist'],
            'languages' => ['All Languages', 'English', 'Arabic', 'Hindi', 'Tagalog'],
            'workTypes' => ['All Types', 'full-time', 'part-time', 'live-in', 'live-out'],
            'skills' => ['All Skills', 'cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'],
            'visaStatuses' => ['All Visa Statuses', 'Residence Visa', 'Tourist Visa', 'Employment Visa', 'Cancelled Visa', 'Own Visa'],
        ];

        return Inertia::render('Employer/Workers/Index', [
            'initialWorkers' => $workers,
            'initialShortlistedIds' => $shortlistedIds,
            'filtersMetadata' => $filtersMetadata,
        ]);
    }

    public function show($id)
    {
        $w = Worker::with(['category', 'skills', 'documents'])->findOrFail($id);

        $isPending = str_contains(strtolower($w->passport_status), 'pending');
        if ($w->status === 'hidden' || $isPending) {
            abort(404);
        }

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

        $langs = $w->language ? array_map('trim', explode(',', $w->language)) : ['English'];

        // Preferred job types: full-time / part-time / live-in / live-out
        $jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
        $preferredJobType = $jobTypes[$w->id % 4];

        $emiratesIdStatus = $w->emirates_id_status;

        // Map skills dynamically from database
        $mappedSkills = $w->skills->pluck('name')->toArray();
        if (empty($mappedSkills)) {
            $mappedSkills = ['cooking', 'cleaning'];
        }

        $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);
        $rating = $reviewsCount > 0 ? round($dbReviews->avg('rating'), 1) : 0;

        $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,
                'category' => $sw->category ? $sw->category->name : 'Helper',
                'salary' => (int) $sw->salary,
                'rating' => 4.7,
                'verified' => (bool) $sw->verified,
            ];
        })->filter()->values()->toArray();

        $visaStatus = $w->visa_status;

        $worker = [
            'id' => $w->id,
            'name' => $w->name,
            'phone' => $w->phone,
            'gender' => $w->gender ?? 'Female',
            'nationality' => $w->nationality,
            'photo' => $photo,
            'emirates_id_status' => $emiratesIdStatus,
            'passport_status' => $w->passport_status,
            'category' => $w->category ? $w->category->name : 'Domestic Worker',
            'skills' => $mappedSkills,
            'visa_status' => $visaStatus,
            'experience' => $w->experience,
            'experience_years' => 5,
            'salary' => (int) $w->salary,
            'religion' => $w->religion,
            'languages' => $langs,
            'age' => $w->age,
            'verified' => (bool) $w->verified,
            'preferred_job_type' => $preferredJobType,
            'live_in_out' => $w->live_in_out ?? 'Live-in',
            'bio' => $w->bio,
            'rating' => $rating,
            'reviews_count' => $reviewsCount,
            'reviews' => $reviews,
            'similar_workers' => $similarWorkers,
            'status' => $w->status,
            'availability_status' => $w->status,
        ];

        return Inertia::render('Employer/Workers/Show', [
            'worker' => $worker,
        ]);
    }

    public function sendOffer(Request $request, $id)
    {
        $request->validate([
            'work_date' => 'required|date',
            'location' => 'required|string|max:255',
            'salary' => 'required|numeric|min:0',
            'notes' => 'nullable|string|max:1000',
        ]);

        $user = $this->resolveCurrentUser();
        $employerId = $user ? $user->id : 2;

        $worker = Worker::findOrFail($id);

        JobOffer::create([
            'employer_id' => $employerId,
            'worker_id' => $worker->id,
            'work_date' => $request->work_date,
            'location' => $request->location,
            'salary' => $request->salary,
            'notes' => $request->notes,
            'status' => 'pending',
        ]);

        return redirect()->route('employer.hiring.success', ['id' => $id])
            ->with('success', 'Hiring offer has been successfully dispatched to the worker!');
    }

    public function markHired(Request $request, $id)
    {
        $user = $this->resolveCurrentUser();
        $employerId = $user ? $user->id : 2;

        $worker = Worker::findOrFail($id);
        $worker->update([
            'status' => 'Hired',
        ]);

        // Check if there is an existing job offer for this employer and worker
        $offer = JobOffer::where('employer_id', $employerId)
            ->where('worker_id', $worker->id)
            ->first();

        if ($offer) {
            $offer->update(['status' => 'accepted']);
        } else {
            // Also check if there's an existing job application
            $jobIds = \App\Models\JobPost::where('employer_id', $employerId)->pluck('id');
            $application = \App\Models\JobApplication::whereIn('job_id', $jobIds)
                ->where('worker_id', $worker->id)
                ->first();

            if ($application) {
                $application->update(['status' => 'hired']);
            } else {
                // Create a new direct job offer with status accepted
                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.',
                    'status' => 'accepted',
                ]);
            }
        }

        return back()->with('success', 'Worker successfully marked as Hired!');
    }
}
