<?php
// app/Http/Controllers/GoalController.php
namespace App\Http\Controllers;

use App\Models\Employee;
use App\Models\Department;
use App\Models\SimpleGoal;
use Illuminate\Http\Request;
use App\Mail\GoalReminderMail;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;

class SimpleGoalController extends Controller
{
    /* Index */
    public function index()
    {
        $user = Auth::user();
        $orgId = $user->organisation_id;
        $isManager = false;

        $canApproveGoals = false;
        if ($user->can('manage goals')) {
            $canApproveGoals = true;
        } else {
            //If the user is an employee and manages any department, they can approve goals
            $currentUserEmployeeRecord = Employee::where('user_id', $user->id)->first();
            if ($currentUserEmployeeRecord && Department::where('manager_id', $currentUserEmployeeRecord->id)->exists()) {
                $canApproveGoals = true;
            }
        }

        if ($user->can('manage goals')) {
            // Super Admin or HR/Admin: all goals in the organisation
            $goals = SimpleGoal::where('organisation_id', $orgId)
                ->latest()
                ->paginate(15);
        } else {
            $employee = Employee::where('user_id', $user->id)->first();

            if (!$employee) {
                // No employee record
                $goals = SimpleGoal::where('id', 0)->latest()->paginate(15);
            } else {
                // Get departments managed by this employee
                $managedDepartmentIds = Department::where('manager_id', $employee->id)
                    ->pluck('id')
                    ->toArray();

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

                    // Employees in those departments
                    $employeeIds = Employee::whereIn('department_id', $managedDepartmentIds)
                        ->pluck('id')
                        ->toArray();

                    // Include the manager's own ID too
                    $employeeIds[] = $employee->id;

                    // Get goals assigned to these employees
                    $goals = SimpleGoal::whereHas('employees', function ($q) use ($employeeIds) {
                        $q->whereIn('simple_goal_employees.employee_id', $employeeIds);
                    })
                        ->where('organisation_id', $orgId)
                        ->latest()
                        ->paginate(15);
                } else {
                    // Regular employee with no managed departments
                    $goals = $employee->simpleGoals()->latest()->paginate(15);
                }
            }
        }

        return view('simple-goals.index', compact('goals', 'isManager', 'canApproveGoals'));
    }

    /* Create form */
    public function create()
    {
        $user = Auth::user();
        $orgId = $user->organisation_id;
        $employeeUser = Employee::where('user_id', $user->id)->first();
        $isManager = false;

        if ($employeeUser) {
            $isManager = Department::where('manager_id', $employeeUser->id)->exists();
        }

        if ($user->can('manage goals')) {
            // Super Admin or HR/Admin: all goals in the organisation
            $goals = SimpleGoal::where('organisation_id', $orgId)
                ->latest()
                ->paginate(15);
        } else {
            $employee = Employee::where('user_id', $user->id)->first();

            if (!$employee) {
                // No employee record
                $goals = collect();
            } else {
                // Get departments managed by this employee
                $managedDepartmentIds = Department::where('manager_id', $employee->id)
                    ->pluck('id')
                    ->toArray();

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

                    // Employees in those departments
                    $employeeIds = Employee::whereIn('department_id', $managedDepartmentIds)
                        ->pluck('id')
                        ->toArray();

                    // Include the manager's own ID too
                    $employeeIds[] = $employee->id;

                    // Get goals assigned to these employees
                    $goals = SimpleGoal::whereHas('employees', function ($q) use ($employeeIds) {
                        $q->whereIn('simple_goal_employees.employee_id', $employeeIds);
                    })
                        ->where('organisation_id', $orgId)
                        ->latest()
                        ->paginate(15);
                } else {
                    // Regular employee with no managed departments
                    $goals = $employee->simpleGoals()->latest()->paginate(15);
                }
            }
        }

        return view('simple-goals.create', compact('isManager', 'goals'));
    }

    /* Store */
    public function store(Request $request)
    {
        $user    = Auth::user();
        $payload = $this->validated($request);
        $payload['organisation_id'] = $user->organisation_id;
        $isAdmin = $user->can('manage goals');
        $isManager = false;
        $employeeUser = Employee::where('user_id', $user->id)->first();

        if ($employeeUser) {
            $isManager = Department::where('manager_id', $employeeUser->id)->exists();
        }


        // 1.  Create the goal itself, 
        //Is active is set to false by default if user is not admin
        if (!$isAdmin) {
            $payload['is_active'] = false; 
        } else if($isManager) {
            $payload['is_active'] = true; // Managers can create active goals
        } else {
            $payload['is_active'] = true; // Fallback for admins
        }

        $goal = SimpleGoal::create($payload);

        // 2.  Build the list of employee-IDs to attach
        $employeeIds = $request->input('employees', []);   // array from the form (managers only)

        // If the creator is a regular employee, auto-attach them
        if (!$user->can('manage goals')) {
            $creatorEmp = Employee::where('user_id', $user->id)->first();
            if ($creatorEmp) {
                $employeeIds[] = $creatorEmp->id;
            }
        }

        // Remove duplicates, just in case
        $employeeIds = array_unique($employeeIds);

        // 3.  Sync pivot rows (with organisation_id on each row)
        $goal->employees()->sync(
            collect($employeeIds)
                ->mapWithKeys(fn($id) => [$id => ['organisation_id' => $payload['organisation_id']]])
        );

        return back()->with('success', __('Goal created.'));
    }

    /* Edit form */
    public function edit(SimpleGoal $SimpleGoal)
    {
        $user = Auth::user();
        $orgId = $user->organisation_id;
        $employeeUser = Employee::where('user_id', $user->id)->first();
        $isManager = false;
        if ($employeeUser) {
            $isManager = Department::where('manager_id', $employeeUser->id)->exists();
        }
        $this->authorizeOrg($SimpleGoal);

        $x = $SimpleGoal->appraisalFeedback();
        // Check via feedback → appraisalReview
        $lockedAppraisal = $SimpleGoal->appraisalFeedback()
            ->whereHas('appraisalReview', function ($q) {
                $q->where('allow_goal_update', false);
            })
            ->first();

        if ($lockedAppraisal) {
            return response()->view('partial.Admin.modal-error', [
                'message' => __('This goal is currently locked for editing because it is under appraisal.')
            ]);
        }


        $assignedEmployeeIds = $SimpleGoal->employees()->pluck('employees.id')->toArray();
        $assignedEmployees = $SimpleGoal->employees()->get();

        //Lets load goal libaray
        if ($user->can('manage goals')) {
            // Super Admin or HR/Admin: all goals in the organisation
            $goals = SimpleGoal::where('organisation_id', $orgId)
                ->latest()
                ->paginate(15);
        } else {
            $employee = Employee::where('user_id', $user->id)->first();

            if (!$employee) {
                // No employee record
                $goals = collect();
            } else {
                // Get departments managed by this employee
                $managedDepartmentIds = Department::where('manager_id', $employee->id)
                    ->pluck('id')
                    ->toArray();

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

                    // Employees in those departments
                    $employeeIds = Employee::whereIn('department_id', $managedDepartmentIds)
                        ->pluck('id')
                        ->toArray();

                    // Include the manager's own ID too
                    $employeeIds[] = $employee->id;

                    // Get goals assigned to these employees
                    $goals = SimpleGoal::whereHas('employees', function ($q) use ($employeeIds) {
                        $q->whereIn('simple_goal_employees.employee_id', $employeeIds);
                    })
                        ->where('organisation_id', $orgId)
                        ->latest()
                        ->paginate(15);
                } else {
                    // Regular employee with no managed departments
                    $goals = $employee->simpleGoals()->latest()->paginate(15);
                }
            }
        }
        return view('simple-goals.edit', compact('SimpleGoal', 'assignedEmployees', 'assignedEmployeeIds', 'isManager', 'goals'));
    }

    public function update(Request $request, SimpleGoal $simpleGoal)
    {
        $this->authorizeOrg($simpleGoal);

        // 1) update main goal columns
        $payload = $this->validated($request);
        $simpleGoal->update($payload);

        // 2) only managers can change employee assignments
        if ($request->has('employees') && $request->user()->can('manage goals')) {
            $simpleGoal->employees()->sync(
                collect($request->input('employees'))
                    ->mapWithKeys(fn($id) => [
                        $id => ['organisation_id' => $request->user()->organisation_id],
                    ])
            );
        }

        return back()->with('success', __('Goal updated.'));
    }
    /* Destroy */
    public function destroy(SimpleGoal $simpleGoal)
    {
        $this->authorizeOrg($simpleGoal);
        $simpleGoal->delete();

        return redirect()
            ->route('simple-goals.index')
            ->with('success', '`Goal deleted.');
    }


    public function activate(SimpleGoal $simpleGoal)
    {
        $currentUser = Auth::user();
        $currentUserEmployeeRecord = Employee::where('user_id', $currentUser->id)->first();

        //Check if the goal is already active
        if ($simpleGoal->is_active) {
            return redirect()->back()->with('info', __('Goal is already activated.'));
        }

        $canActivate = false;

        if ($currentUser->can('manage goals')) {
            $canActivate = true;
        } else {
            //Check if current user is a manager of any department the goal's assigned employees belong to
            if ($currentUserEmployeeRecord) {
                $managedDepartmentIds = Department::where('manager_id', $currentUserEmployeeRecord->id)
                                                    ->pluck('id')
                                                    ->toArray();

                // Check if any employee assigned to this goal is in a department managed by the current user
                $goalAssignedEmployeeDepartmentIds = $simpleGoal->employees()->pluck('department_id')->toArray();

                foreach ($goalAssignedEmployeeDepartmentIds as $deptId) {
                    if (in_array($deptId, $managedDepartmentIds)) {
                        $canActivate = true;
                        break; //Found a managed department.
                    }
                }
            }
        }

        // If not authorized, abort
        if (!$canActivate) {
            abort(403, __('You are not authorized to activate this goal.'));
        }

        // Activate the goal
        $simpleGoal->update(['is_active' => true]);

        return redirect()->back()->with('success', __('Goal activated successfully.'));
    }


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

        if ($userIsAdmin) {
            $departments = Department::where('organisation_id', $user->organisation_id)->pluck('name', 'id');
            Log::info('dd',[$departments]);
            return view('simple-goals.notify_modal', compact('userIsAdmin', 'departments', 'isManager'));
        }

        // Manager logic
        $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('simple-goals.notify_modal', compact('isManager', 'department', 'employees', 'userIsAdmin')); // also pass userIsAdmin
            }
        }
        
        // If the user is neither an admin nor a manager, we still need to pass these variables
        return response()->view('simple-goals.notify_modal', compact('userIsAdmin', 'isManager'), 403);
    }

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

        $recipients = collect();

        // Admin logic
        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();
            }
        }
        
        // Manager logic (only one department allowed)
        $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.');
        }

        // Send an email to each recipient
        foreach ($recipients as $employee) {
            if ($employee->user) {
                try {
                    Mail::to($employee->user->email)->send(new GoalReminderMail($employee));
                } catch (\Exception $e) {
                    // Log the error but continue sending to other employees
                    \Log::error("Failed to send goal reminder to {$employee->user->email}: " . $e->getMessage());
                }
            }
        }

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


    /* ---- helpers ---- */
    protected function validated(Request $r): array
    {
        return $r->validate([
            'title'                  => 'required|string|max:255',
            'description'            => 'nullable|string',
            'start_date'             => 'nullable|date',
            'due_date'               => 'nullable|date|after_or_equal:start_date',
            'status'                 => 'required',
            'is_visible_to_employee' => 'boolean',
            'weight'                 => 'nullable|integer|min:0|max:100',
        ]);
    }

    protected function authorizeOrg(SimpleGoal $SimpleGoal): void
    {
        if ($SimpleGoal->organisation_id !== Auth::user()->organisation_id) {
            abort(40, 'Unauthorized');
        }
    }
}
