<?php

namespace App\Http\Controllers;

use App\Models\AppraisalFinalScore;
use App\Models\User;
use App\Models\Employee;
use App\Models\Department;
use App\Models\RatingType;
use App\Models\SimpleGoal;
use App\Mail\PeerAddedMail;
use App\Models\Competencies;
use Illuminate\Http\Request;
use App\Models\AppraisalReview;
use App\Models\RatingTypeMetric;
use App\Models\WeightedCriteria;
use App\Models\FinalRatingAction;
use App\Mail\AppraisalCreatedMail;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use App\Models\AppraisalReviewFeedback;
use App\Mail\AppraisalReviewReminderMail;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\CompensationOutcomesExport;


class AppraisalReviewController extends Controller
{


    public function index()
    {
        $user = Auth::user();
        $orgId = $user->organisation_id;
        $userIsAdmin = $user->can('manage goals');

        // Initialize a base query for Appraisal Reviews, eager load employee data
        $query = AppraisalReview::with('employee');

        // Initialize a flag for employee status
        $isEmployee = false;

        if ($userIsAdmin) {
            // Admins: see all appraisal reviews within their organization
            $query->whereHas('employee', function ($q) use ($orgId) {
                $q->where('organisation_id', $orgId);
            });
        } else {
            // For non-admin users, we need to determine their specific context (employee, manager, peer)
            $employeeRecord = Employee::where('user_id', $user->id)->first();

            if ($employeeRecord) {
                // Set the isEmployee flag
                $isEmployee = true;

                $isManager = false;

                // Check if the current user manages any departments
                $managedDepartmentIds = Department::where('manager_id', $employeeRecord->id)
                    ->pluck('id')
                    ->toArray();

                if (!empty($managedDepartmentIds)) {
                    $isManager = true;
                }

                // Build the main WHERE clause using a nested function to group OR conditions
                $query->where(function ($q) use ($employeeRecord, $isManager, $managedDepartmentIds) {
                    // Condition 1: Include appraisals where the current user is the employee being reviewed
                    $q->where('employee_id', $employeeRecord->id);

                    // Condition 2: If the user is a manager, include appraisals for employees in their managed departments
                    if ($isManager) {
                        $managedEmployeeIds = Employee::whereIn('department_id', $managedDepartmentIds)
                            ->pluck('id')
                            ->toArray();

                        $q->orWhereIn('employee_id', $managedEmployeeIds);
                    }

                    // Condition 3: Include appraisals where the current user is a peer
                    $q->orWhereHas('peers', function ($qPeer) use ($employeeRecord) {
                        $qPeer->where('appraisal_review_peers.employee_id', $employeeRecord->id);
                    });
                });
            } else {
                // If the user is not an admin and has no employee record, they shouldn't see any appraisals.
                $query->whereRaw('1 = 0');
            }
        }

        // Apply ordering and pagination
        $appraisals = $query->latest()->paginate(20);

        // Pass the new variable to the view
        return view('appraisal_reviews.index', compact('appraisals', 'userIsAdmin', 'isEmployee'));
    }





    public function compensationOutcome()
    {
        $user = Auth::user();
        $orgId = $user->organisation_id;
        $userIsAdmin = $user->can('manage goals');

        // Initialize a base query for Appraisal Reviews, eager load employee data

        // Initialize a flag for employee status
        $isEmployee = false;

        $outcomes = AppraisalFinalScore::with(['appraisal_review.employee'])->paginate(20);


        // Pass the new variable to the view
        return view('appraisal_reviews.outcomes', compact('outcomes', 'userIsAdmin', 'isEmployee'));
    }

    public function export()
    {
        return Excel::download(new CompensationOutcomesExport, 'compensation_outcomes.xlsx');
    }

    public function create()
    {
        $currentUser = Auth::user();
        $orgId = Auth::user()->organisation_id;
        $employees = Employee::where('organisation_id', $orgId)->pluck('name', 'id');
        $goals = SimpleGoal::where('organisation_id', $orgId)->pluck('title', 'id');
        $competencies = Competencies::where('organisation_id', $orgId)->pluck('name', 'id');
        $ratingTypes = RatingType::pluck('name', 'id');

        return view('appraisal_reviews.create', compact('employees', 'goals', 'ratingTypes', 'competencies'));
    }

    public function store(Request $r)
    {
        $data = $r->validate([
            'appraisal_date' => 'required',
            'employee_id' => 'required|exists:employees,id',
            'rating_type_id' => 'required|exists:rating_types,id',
            'goal_ids' => 'array',
            'allow_goal_update' => 'boolean',
            'review_type' => 'required|in:90,180,360',
        ]);

        $data['status'] = 'on_going';
        $data['review_type'] = $r->review_type;

        $data['created_by'] = Auth::id();
        $data['organisation_id'] = Auth::user()->organisation_id;


        $appraisal = AppraisalReview::create($data);

        if ($appraisal->employee && $appraisal->employee->user) {
            try {
                Mail::to($appraisal->employee->user->email)->send(new AppraisalCreatedMail($appraisal));
            } catch (\Exception $e) {
                Log::error("Failed to send appraisal creation email to {$appraisal->employee->user->email}: " . $e->getMessage());
            }
        }
        // attach selected goals
        $goalIds = $r->input('goal_ids', []);
        $pivotData = [];
        $compentencyPivotData = [];

        foreach ($goalIds as $goalId) {
            $pivotData[$goalId] = ['organisation_id' => Auth::user()->organisation_id];
        }
        // attach competencies
        $competencyIds = $r->input('competencies', []);
        Log::info('Competency IDs: ', $competencyIds);
        foreach ($competencyIds as $competencyId) {
            $compentencyPivotData[$competencyId] = [
                'weight' => 0, // default weight
                'rating' => null, // default rating
                'comment' => null, // default comment
                'organisation_id' => Auth::user()->organisation_id,
            ];
        }
        $appraisal->competencies()->sync($compentencyPivotData);
        $appraisal->goals()->sync($pivotData);


        /* ------------------------------------------------------
       5)  insert feedback rows
       expected payload shape:
       ratings[<goalId>][manager_rating|manager_comment|employee_rating|...]
       ------------------------------------------------------ */
        $feedbackInput = $r->input('ratings', []);   // array|null
        $rows = [];

        foreach ($feedbackInput as $goalId => $values) {
            foreach (['manager', 'employee', 'admin'] as $role) {
                $rating = $values["{$role}_rating"] ?? null;
                $comment = $values["{$role}_comment"] ?? null;

                // skip completely empty rows
                if ($rating === null && $comment === null)
                    continue;

                $rows[] = [
                    'appraisal_review_id' => $appraisal->id,
                    'simple_goal_id' => $goalId,
                    'giver_role' => $role,       // enum('manager','employee','admin')
                    'rating_value' => $rating,
                    'comment' => $comment,
                    'organisation_id' => $data['organisation_id'],
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
        }

        if ($rows) {
            AppraisalReviewFeedback::insert($rows);
        }

        return redirect()->route('appraisal_reviews.index')->with('success', __('Appraisal created.'));
    }

    public function edit(AppraisalReview $appraisalReview)
    {
        $this->authorizeOrg($appraisalReview);

        $currentUser = Auth::user();
        $orgId = $currentUser->organisation_id;
        $employees = Employee::where('organisation_id', $orgId)->pluck('name', 'id');
        $availableGoals = SimpleGoal::where('organisation_id', $orgId)->where('is_active', true)->pluck('title', 'id');
        $availableCompetencies = Competencies::where('organisation_id', $orgId)->get(['id', 'name']);
        $ratingTypes = RatingType::where('organisation_id', $orgId)->pluck('name', 'id');
        $ratingTypesWithConfig = RatingType::where('organisation_id', $orgId)->pluck('config', 'id')->map(function ($item) {
            return json_decode($item, true);
        });
        $isManager = false;
        $employeeRecord = Employee::where('user_id', $currentUser->id)->first();
        $userIsAdmin = $currentUser->can('manage goals');
        $allowEditAfterFinalScore = ($appraisalReview->final_score === null);

        //Employee who owns the review
        $employee = $appraisalReview->employee;

        $isEmployee = $employeeRecord->id === $appraisalReview->employee_id;

        //Fetch if employee is a manager
        if ($employeeRecord) {
            $managedDepartmentIds = Department::where('manager_id', $employeeRecord->id)
                ->pluck('id')
                ->toArray();

            $isManager = in_array($employee->department_id, $managedDepartmentIds);
        }


        //Check if user is a peer
        $isPeer = ($appraisalReview->review_type === '360' && $appraisalReview->peers->contains($employeeRecord->id));

        $preloadedGoals = $appraisalReview->goals->map(fn($g) => [
            'id' => $g->id,
            'title' => $g->title,
            'due_date' => $g->due_date,
        ])->values();

        $preloadedCompetencies = $appraisalReview->competencies()->get();


        $potentialPeers = collect();
        $selectedPeerIds = [];

        if (($userIsAdmin || $isManager) && $appraisalReview->review_type === '360') {
            $potentialPeers = User::where('organisation_id', $orgId)
                ->whereHas('employee') //Only users who have an associated employee record
                ->when($employee, function ($query) use ($employee) {
                    $query->where('id', '!=', $employee->user_id);
                })
                ->where('id', '!=', $currentUser->id)
                ->get()
                ->map(function ($user) {
                    if ($user->employee) {
                        return [
                            'id' => $user->employee->id,
                            'name' => $user->employee->name . ' - ' . (optional($user->employee->department)->name ?? 'N/A')
                        ];
                    }
                    // Fallback if no employee record (shouldn't happen with whereHas('employee'))
                    return [
                        'id' => $user->id,
                        'name' => $user->name . ' - N/A'
                    ];
                });

            $selectedPeerIds = $appraisalReview->peers->pluck('id')->toArray();
        }

        // --- NEW: Fetch single peer feedback for the peer form ---
        $peerFeedback = null;
        if ($isPeer) {
            $peerFeedback = AppraisalReviewFeedback::where('appraisal_review_id', $appraisalReview->id)
                ->where('giver_role', 'peer')
                ->where('feedback_by', $currentUser->id)
                ->whereNull('simple_goal_id')
                ->whereNull('competency_id')
                ->first();
        }

        $allPeerFeedbacks = [];
        // Only fetch if the user is not a peer (i.e. manager, admin, employee being reviewed)
        if (!$isPeer) {
            $allPeerFeedbacks = AppraisalReviewFeedback::where('appraisal_review_id', $appraisalReview->id)
                ->where('giver_role', 'peer')
                ->whereNull('simple_goal_id')
                ->whereNull('competency_id')
                ->with('giverUser.employee')
                ->get()
                ->map(fn($fb) => [
                    'rating_value' => $fb->rating_value,
                    'comment' => $fb->comment,
                    'giver_name' => $fb->giverUser->employee->name ?? $fb->giverUser->name ?? 'Unknown Peer',
                ]);
        }


        $feedback = AppraisalReviewFeedback::where('appraisal_review_id', $appraisalReview->id)
            ->with('giverUser.employee')
            ->get();

        $feedbackByGoalRole = [];
        $feedbackByCompetencyRole = [];

        foreach ($feedback as $fb) {
            $itemId = $fb->simple_goal_id ?? $fb->competency_id;
            $itemType = $fb->simple_goal_id ? 'goal' : 'competency';

            // We only need to process manager/employee/admin feedback here,
            // as peer feedback is now handled separately.
            if ($fb->giver_role !== 'peer') {
                if ($itemType === 'goal' && !isset($feedbackByGoalRole[$itemId])) {
                    $feedbackByGoalRole[$itemId] = [];
                } elseif ($itemType === 'competency' && !isset($feedbackByCompetencyRole[$itemId])) {
                    $feedbackByCompetencyRole[$itemId] = [];
                }

                $feedbackData = [
                    'rating_value' => $fb->rating_value,
                    'comment' => $fb->comment,
                ];

                if ($itemType === 'goal') {
                    $feedbackByGoalRole[$itemId][$fb->giver_role] = $feedbackData;
                } else {
                    $feedbackByCompetencyRole[$itemId][$fb->giver_role] = $feedbackData;
                }
            }
        }

        // Log::info('Manager', ['isManager' => $isManager, 'isEmployee' => $isEmployee, 'isPeer' => $isPeer, 'userIsAdmin' => $userIsAdmin, 'currentUser' => $currentUser->id]);

        Log::info('peers', ['SP' => $selectedPeerIds, 'PP' => $potentialPeers, 'isEmployee' => $isEmployee]);
        //        // Log::info('feedbackByCompetencyRole', $peerFeedbackData);

        return view('appraisal_reviews.edit', compact(
            'appraisalReview',
            'employees',
            'availableGoals',
            'availableCompetencies',
            'ratingTypes',
            'ratingTypesWithConfig',
            'preloadedGoals',
            'feedbackByGoalRole',
            'employee',
            'isEmployee',
            'isManager',
            'isPeer',
            'userIsAdmin',
            'preloadedCompetencies',
            'feedbackByCompetencyRole',
            'allowEditAfterFinalScore',
            'potentialPeers',
            'selectedPeerIds',
            'peerFeedback',
            'allPeerFeedbacks'
        ));
    }

    public function update(Request $r, AppraisalReview $appraisalReview)
    {
        $this->authorizeOrg($appraisalReview);
        $currentUser = Auth::user();
        $currentUserEmployeeRecord = Employee::where('user_id', $currentUser->id)->first();

        // Determine user roles using the same, corrected logic as the edit method
        $employeeBeingReviewed = $appraisalReview->employee; // Employee who owns the review

        $isEmployee = ($currentUserEmployeeRecord && $currentUserEmployeeRecord->id === $employeeBeingReviewed->id);

        $isManager = false;
        if ($currentUserEmployeeRecord && $employeeBeingReviewed) {
            $managedDepartmentIds = Department::where('manager_id', $currentUserEmployeeRecord->id)
                ->pluck('id')
                ->toArray();
            // Current user manages the department the employee being reviewed is in
            $isManager = in_array($employeeBeingReviewed->department_id, $managedDepartmentIds);
        }

        $userIsAdmin = $currentUser->can('manage goals'); // Or 'manage appraisals'


        $isPeer = ($appraisalReview->review_type === '360' && $appraisalReview->peers->contains($currentUserEmployeeRecord->id));


        $data = $r->all();
        $appraisalReview->update($data); // This updates the main appraisal review fields (like status, review_type, etc.)

        // Sync goals and competencies first, as they define the items for feedback
        // Attach selected goals
        $goalIds = $r->input('goal_ids', []);
        $pivotData = [];
        foreach ($goalIds as $goalId) {
            $pivotData[$goalId] = ['organisation_id' => Auth::user()->organisation_id];
        }
        $appraisalReview->goals()->sync($pivotData);

        // Sync selected competencies
        $competencyIds = $r->input('competency_ids', []);
        $pivotDataCompetencies = [];
        foreach ($competencyIds as $competencyId) {
            $pivotDataCompetencies[$competencyId] = ['organisation_id' => Auth::user()->organisation_id];
        }
        $appraisalReview->competencies()->sync($pivotDataCompetencies);
        $ratingsInput = $r->input('ratings', []);

        $originalPeerIds = $appraisalReview->peers->pluck('id')->toArray();

        // Only allow Admin or Manager to sync peers, and only if review type is 360
        if (($userIsAdmin || $isManager) && $appraisalReview->review_type === '360') {
            $peerEmployeeIds = $r->peer_ids ?? [];
            $appraisalReview->peers()->sync(
                collect($peerEmployeeIds)
                    ->mapWithKeys(fn($id) => [$id => ['organisation_id' => Auth::user()->organisation_id]])
            );
            $newPeerIds = array_diff($peerEmployeeIds, $originalPeerIds);

            if (!empty($newPeerIds)) {
                $newPeers = Employee::whereIn('id', $newPeerIds)->with('user')->get();
                foreach ($newPeers as $peer) {
                    if ($peer->user) {
                        try {
                            Mail::to($peer->user->email)->send(new PeerAddedMail($appraisalReview, $peer));
                        } catch (\Exception $e) {
                            Log::error("Failed to send peer added email to {$peer->user->email}: " . $e->getMessage());
                        }
                    }
                }
            }
        } elseif ($appraisalReview->review_type !== '360') {
            // If review type is changed from 360, clear existing peers
            $appraisalReview->peers()->detach();
        }
        // Process Goal Feedback
        if (isset($ratingsInput['goal'])) {
            foreach ($ratingsInput['goal'] as $goalId => $values) {
                // Handle Manager, Employee, Admin feedback for goals
                foreach (['manager', 'employee', 'admin'] as $role) {
                    // Check if current user has permission to update this role's feedback
                    if (
                        ($role === 'manager' && !$isManager) ||
                        ($role === 'employee' && !$isEmployee) ||
                        ($role === 'admin' && !$userIsAdmin)
                    ) {
                        continue; // Skip if user doesn't have permission for this role's feedback
                    }

                    $rating = $values["{$role}_rating"] ?? null;
                    $comment = $values["{$role}_comment"] ?? null;

                    // If both rating and comment are empty, and there's no existing record, we don't create one.
                    // If they are empty and there IS an existing record, we update it with nulls or remove it.
                    // For manager/employee/admin, typically we'd update with nulls if cleared.
                    if ($rating === null && $comment === null) {
                        // Optionally: Delete the feedback if cleared
                        AppraisalReviewFeedback::where('appraisal_review_id', $appraisalReview->id)
                            ->where('simple_goal_id', $goalId)
                            ->where('giver_role', $role)
                            ->delete();
                        continue; // Move to next role/item
                    }

                    AppraisalReviewFeedback::updateOrCreate(
                        [
                            'appraisal_review_id' => $appraisalReview->id,
                            'simple_goal_id' => $goalId,
                            'competency_id' => null, // Ensure correct column is null
                            'giver_role' => $role,
                            'feedback_by' => null, // Standard roles usually don't have a specific giver_id
                            'organisation_id' => Auth::user()->organisation_id,
                        ],
                        [
                            'rating_value' => $rating,
                            'comment' => $comment,
                            // created_at/updated_at handled by Laravel's Eloquent
                        ]
                    );
                }

            }
        }
        // Process Competency Feedback (similar logic as goals)
        if (isset($ratingsInput['competency'])) {
            foreach ($ratingsInput['competency'] as $competencyId => $values) {
                // Handle Manager, Employee, Admin feedback for competencies


                foreach (['manager', 'employee', 'admin'] as $role) {
                    // Check if current user has permission to update this role's feedback
                    if (
                        ($role === 'manager' && !$isManager) ||
                        ($role === 'employee' && !$isEmployee) ||
                        ($role === 'admin' && !$userIsAdmin)
                    ) {
                        continue; // Skip if user doesn't have permission for this role's feedback
                    }
                    // return [$ratingsInput['competency'], $role, $competencyId];

                    $rating = $values["{$role}_rating"] ?? null;
                    $comment = $values["{$role}_comment"] ?? null;

                    if ($rating === null && $comment === null) {
                        // Optionally: Delete the feedback if cleared
                        AppraisalReviewFeedback::where('appraisal_review_id', $appraisalReview->id)
                            ->where('competency_id', $competencyId)
                            ->where('giver_role', $role)
                            ->delete();
                        continue;
                    }

                    AppraisalReviewFeedback::updateOrCreate(
                        [
                            'appraisal_review_id' => $appraisalReview->id,
                            'simple_goal_id' => null,
                            'competency_id' => $competencyId,
                            'giver_role' => $role,
                            'feedback_by' => null,
                            'organisation_id' => Auth::user()->organisation_id,
                        ],
                        [
                            'rating_value' => $rating,
                            'comment' => $comment,
                        ]
                    );
                }
            }
        }

        if ($isPeer && $appraisalReview->review_type === '360') {
            $rating = $r->input('peer_rating') ?? null;
            $comment = $r->input('peer_comment') ?? null;

            // This is the crucial update: we update a single record
            AppraisalReviewFeedback::updateOrCreate(
                [
                    'appraisal_review_id' => $appraisalReview->id,
                    'giver_role' => 'peer',
                    'feedback_by' => $currentUser->id,
                    'organisation_id' => Auth::user()->organisation_id,
                    'simple_goal_id' => null, // Ensure this record is not tied to a goal
                    'competency_id' => null, // Ensure this record is not tied to a competency
                ],
                [
                    'rating_value' => $rating,
                    'comment' => $comment,
                ]
            );
        }
        // Log::info('All Feedback Rows: ', $allFeedbackRows); // No longer needed as we're not batch inserting
        // if ($allFeedbackRows) {
        //     AppraisalReviewFeedback::insert($allFeedbackRows); // REMOVED
        // }

        return redirect()
            ->route('appraisal_reviews.index')
            ->with('success', __('Appraisal updated.'));
    }
    public function destroy(AppraisalReview $appraisalReview)
    {
        $this->authorizeOrg($appraisalReview);

        $appraisalReview->delete();   // pivot rows cascade if FK with cascadeOnDelete

        return redirect()
            ->route('appraisal_reviews.index')
            ->with('success', __('Appraisal deleted.'));
    }

    /* ----------------------------------------------------
     |  Helper: ensure appraisal reviews belongs to same organisation
     * ---------------------------------------------------- */
    protected function authorizeOrg(AppraisalReview $appraisal): void
    {
        $orgId = Auth::user()->organisation_id;

        if ($appraisal->employee->organisation_id !== $orgId) {
            abort(403, __('Permission denied.'));
        }
    }

    public function getGoalsForEmployee($employeeId)
    {
        $orgId = Auth::user()->organisation_id;

        $goals = SimpleGoal::where('organisation_id', $orgId)
            ->whereHas('employees', function ($q) use ($employeeId) {
                $q->where('simple_goal_employees.employee_id', $employeeId);
            })
            ->select('id', 'title', 'due_date', 'status')
            ->get();

        return response()->json($goals);
    }


    public function closeAppraisal(AppraisalReview $appraisalReview)
    {
        $this->authorizeOrg($appraisalReview);


        $user = Auth::user();
        $orgId = $user->organisation_id;

        if ($appraisalReview->status !== 'on_going') {
            return redirect()->back()->with('error', __('Appraisal review cannot be closed as it is not in an "on-going" status.'));
        }

        $finalScore = 'ungraded';

        // Ensure only authorized users can finalize the review
        if (!Auth::user()->can('manage goals')) {
            return redirect()->back()->with('error', 'You are not authorized to finalize this appraisal.');
        }

        // Get the manager's goal feedback ratings
        $managerGoalFeedbacks = $appraisalReview->feedback()
            ->where('giver_role', 'manager')
            ->whereNotNull('simple_goal_id')
            ->whereNull('competency_id')
            ->with('simpleGoal')
            ->get();

        $totalScore = 0;
        $totalWeight = 0;

        // Use the rating type associated with the appraisal review itself
        $ratingType = $appraisalReview->ratingType;
        $ratingTypeId = $ratingType ? $ratingType->id : null;

        if (!$ratingTypeId) {
            return redirect()->back()->with('error', 'The appraisal review does not have a rating type assigned.');
        }

        DB::beginTransaction();

        try {
            foreach ($managerGoalFeedbacks as $feedback) {
                $ratingValue = (float) $feedback->rating_value;
                $goalWeight = (float) $feedback->simpleGoal->weight;
                $metric = null;
                // Handle different rating types
                if ($ratingType->type === 'numeric' || $ratingType->type === 'percentage') {
                    // For range-based ratings, find the metric where the rating value falls within the range
                    $metrics = RatingTypeMetric::where('rating_type_id', $ratingTypeId)->get();
                    foreach ($metrics as $m) {
                        [$min, $max] = explode('-', $m->rating_value);
                        if ($ratingValue >= (float) $min && $ratingValue <= (float) $max) {
                            $metric = $m;
                            break;
                        }
                    }
                    if (!$metric) {
                        $metric = $ratingValue;
                    }
                } else {
                    // For text-based ratings, find the metric by direct match
                    $metric = RatingTypeMetric::where('rating_type_id', $ratingTypeId)
                        ->where('rating_value', $feedback->rating_value)
                        ->where('organisation_id', $orgId)
                        ->first();
                }

                // If a metric is found, calculate the score for this goal
                if ($metric) {
                    // Goal Score = (Metric Value / 100) * Goal Weight
                    $goalScore = ($metric->metric_value ?? $metric / 100) * $goalWeight;
                    $totalScore += $goalScore;
                    $totalWeight += $goalWeight;
                } else {
                    Log::warning("No metric found for rating_type_id: {$ratingTypeId} and rating_value: {$ratingValue}");
                }
            }

            // return $totalWeight;

            $finalScore = ($totalWeight > 0) ? ($totalScore / $totalWeight) * 100 : 0;

            $finalScore = round($finalScore, 2);
            $appraisalReview->update([
                'status' => 'closed',
                'final_score' => $finalScore,
                'allow_goal_update' => false,
            ]);

            DB::commit();

            return redirect()->route('appraisal_reviews.index')->with('success', 'Appraisal finalized and final score calculated.');

        } catch (\Exception $e) {
            DB::rollback();
            Log::error("Failed to finalize appraisal: " . $e->getMessage());
            return redirect()->back()->with('error', 'An error occurred while finalizing the appraisal.');
        }

    }

    public function processFinalScore(AppraisalReview $appraisalReview)
    {
        // Find the matching final rating action based on the calculated score
        $finalRatingAction = FinalRatingAction::where('min_score', '<=', $appraisalReview->final_score)
            ->where('max_score', '>=', $appraisalReview->final_score)
            ->first();

        if (!$finalRatingAction) {
            return response()->json(['error' => 'No final action policy found for this score.'], 404);
        }

        return view('appraisal_final_scores.create', compact('appraisalReview', 'finalRatingAction'));
    }

    public function createNotificationModal()
    {
        $user = Auth::user();
        $userIsAdmin = $user->can('manage goals');
        $isManager = false;

        if ($userIsAdmin) {
            $departments = Department::where('organisation_id', $user->organisation_id)->pluck('name', 'id');
            return view('appraisal_reviews.notify_modal', compact('userIsAdmin', 'departments', 'isManager'));
        }

        $employeeRecord = Employee::where('user_id', $user->id)->first();
        if ($employeeRecord && $employeeRecord->department) {
            $isManager = Department::where('manager_id', $employeeRecord->id)->exists();
            if ($isManager) {
                $department = $employeeRecord->department;
                $employees = Employee::where('department_id', $department->id)->get();
                return view('appraisal_reviews.notify_modal', compact('isManager', 'department', 'employees', 'userIsAdmin'));
            }
        }

        return response()->view('appraisal_reviews.notify_modal', compact('userIsAdmin', 'isManager'), 403);
    }

    /**
     * Send appraisal review reminder notifications.
     */
    public function sendNotifications(Request $request)
    {
        $user = Auth::user();
        $userIsAdmin = $user->can('manage goals');

        $recipients = collect();

        if ($userIsAdmin) {
            $type = $request->input('type');
            if ($type === 'all_employees') {
                $recipients = Employee::where('organisation_id', $user->organisation_id)->get();
            } elseif ($type === 'departments' && $request->has('departments')) {
                $departments = $request->input('departments');
                $recipients = Employee::whereIn('department_id', $departments)->get();
            }
        }

        $employeeRecord = Employee::where('user_id', $user->id)->first();
        if ($employeeRecord && $employeeRecord->department) {
            $isManager = Department::where('manager_id', $employeeRecord->id)->exists();
            if ($isManager) {
                $recipients = Employee::where('department_id', $employeeRecord->department->id)->get();
            }
        }

        if ($recipients->isEmpty()) {
            return redirect()->back()->with('error', 'No employees were selected to receive notifications.');
        }

        foreach ($recipients as $employee) {
            if ($employee->user) {
                try {
                    Mail::to($employee->user->email)->send(new AppraisalReviewReminderMail($employee));
                    Log::info('Mail Sent', [$employee]);
                } catch (\Exception $e) {
                    \Log::error("Failed to send review reminder to {$employee->user->email}: " . $e->getMessage());
                }
            }
        }

        return redirect()->back()->with('success', 'Appraisal review reminders have been sent successfully!');
    }
}
