<?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\JobApplication;
use App\Models\JobPost;
use App\Models\JobOffer;

class CandidateController 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;

        // 1. Get job posts created by this employer
        $jobIds = JobPost::where('employer_id', $employerId)->pluck('id');

        // Fetch applications for those jobs
        $applications = JobApplication::whereIn('job_id', $jobIds)
            ->with(['worker.category', 'jobPost'])
            ->get();

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

            // Map DB status to UI friendly status
            $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);

            return [
                'id' => $app->id, // standard application id
                'worker_id' => $w->id,
                'name' => $w->name,
                'nationality' => $w->nationality,
                'category' => $w->category ? $w->category->name : 'General Helper',
                'salary' => (int)$w->salary,
                'status' => $status,
                'applied_at' => $app->created_at->format('M d, Y'),
                'preferred_location' => $w->preferred_location,
                'preferred_job_type' => $w->preferred_job_type,
                'live_in_out' => $w->live_in_out,
                'in_country' => (bool)$w->in_country,
                'visa_status' => $w->visa_status,
            ];
        })->filter()->values()->toArray();

        // 2. Fetch direct hiring offers sent by this employer
        $directOffers = JobOffer::where('employer_id', $employerId)
            ->with('worker.category')
            ->get();

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

            // Map DB offer status to UI friendly status
            $status = 'Offer Sent';
            if ($offer->status === 'accepted') $status = 'Hired';
            elseif ($offer->status === 'rejected') $status = 'Rejected';
            elseif ($offer->status === 'pending') $status = 'Offer Sent';

            return [
                'id' => 'offer_' . $offer->id, // Unique string key prefix to prevent clashes
                'worker_id' => $w->id,
                'name' => $w->name,
                'nationality' => $w->nationality,
                'category' => $w->category ? $w->category->name : 'General Helper',
                'salary' => (int)$offer->salary,
                'status' => $status,
                'applied_at' => $offer->created_at->format('M d, Y'),
                'preferred_location' => $w->preferred_location,
                'preferred_job_type' => $w->preferred_job_type,
                'live_in_out' => $w->live_in_out,
                'in_country' => (bool)$w->in_country,
                'visa_status' => $w->visa_status,
            ];
        })->filter()->values()->toArray();

        // Merge standard job applications with direct hiring offers for unified tracking
        $mergedCandidates = array_merge($selectedWorkers, $directWorkers);

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

        // Apply 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);
            
            $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;
            }));
        }

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

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

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

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

        return Inertia::render('Employer/SelectedCandidates', [
            'selectedWorkers' => $mergedCandidates,
        ]);
    }

    public function updateStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|string|in:Reviewing,Offer Sent,Hired,Rejected',
        ]);

        // If this is a direct hiring offer response
        if (is_string($id) && str_starts_with($id, 'offer_')) {
            $offerId = substr($id, 6);
            $offer = JobOffer::findOrFail($offerId);
            
            $dbStatus = 'pending';
            if ($request->status === 'Hired') {
                $dbStatus = 'accepted';
                $offer->worker->update(['status' => 'Hired']);
            } elseif ($request->status === 'Rejected') {
                $dbStatus = 'rejected';
                $offer->worker->update(['status' => 'active']);
            } elseif ($request->status === 'Offer Sent') {
                $dbStatus = 'pending';
            }

            $offer->update(['status' => $dbStatus]);

            return back()->with('success', 'Direct candidate hiring offer status updated successfully to ' . $request->status);
        }

        // Standard job application status update
        $app = JobApplication::findOrFail($id);

        $dbStatus = 'applied';
        if ($request->status === 'Hired') {
            $dbStatus = 'hired';
            if ($app->worker) {
                $app->worker->update(['status' => 'Hired']);
            }
        } elseif ($request->status === 'Rejected') {
            $dbStatus = 'rejected';
            if ($app->worker) {
                $app->worker->update(['status' => 'active']);
            }
        } elseif ($request->status === 'Offer Sent') {
            $dbStatus = 'shortlisted';
        } elseif ($request->status === 'Reviewing') {
            $dbStatus = 'applied';
        }

        $app->update([
            'status' => $dbStatus,
        ]);

        return back()->with('success', 'Candidate application status updated successfully to ' . $request->status);
    }
}
