<?php

namespace App\Http\Requests\Admin;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;
use App\Models\DepartmentUser;
use App\Models\Department;
use App\Models\Prabhag;
use App\Models\PrabhagWard;
use App\Models\WaterPrabhag;
use App\Models\WaterPrabhagWards;
use App\Models\Ward;

class UpdateUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        $userId = $this->route('user'); // Get user ID from route

        $rules = [
            'user_id' => 'required',
            'role' => 'required',
            'name' => 'required',
            'email' => [
                'required',
                'email',
                Rule::unique('users', 'email')->ignore($userId),
            ],
            'mobile' => [
                'required',
                'digits:10',
                Rule::unique('users', 'mobile')->ignore($userId),
            ],
            'departments' => 'required|array',
            'departments.*' => 'required|integer', // Multiple departments allowed
        ];

        // Iterate over the departments for dynamic validation
        $departments = $this->input('departments', []);
        foreach ($departments as $index => $departmentId) {
            // Water Department (ID 5)
            if ($departmentId == 5) { // Water Department
                $rules["water_prabhag.$index"] = 'required|array';
                $rules["water_prabhag.$index.*"] = 'required|integer';
                $rules["prabhagward.$index"] = 'required|array';
                $rules["prabhagward.$index.*"] = 'required|integer';
            }
            // Normal Prabhag Department (ID 4)
            elseif ($departmentId == 4) { // Normal Prabhag Department
                $rules["prabhag.$index"] = 'required|array';
                $rules["prabhag.$index.*"] = 'required|integer';
                $rules["prabhagward.$index"] = 'required|array';
                $rules["prabhagward.$index.*"] = 'required|integer';
            }
            // General Ward-based Department
            else { // General Departments
                $rules["wards.$index"] = 'required|array';
                $rules["wards.$index.*"] = 'required|integer';
            }
        }

        return $rules;
    }

    public function messages(): array
    {
        return [
            'name.required' => 'Please enter the user name.',
            'email.required' => 'Please enter a valid email address.',
            'email.unique' => 'This email is already taken.',
            'mobile.required' => 'Please enter mobile number.',
            'mobile.digits' => 'Mobile number must be 10 digits.',
            'mobile.unique' => 'This mobile number is already taken.',
            'departments.required' => 'Please select at least one department.',
            'departments.*.required' => 'Each department must be selected.',

            // Water Department
            'water_prabhag.*.required' => 'Please select at least one water prabhag for each department.',
            'water_prabhag.*.*.required' => 'Please select a water prabhag.',
            'prabhagward.*.required' => 'Please select at least one ward for each water prabhag.',
            'prabhagward.*.*.required' => 'Please select a ward for the selected water prabhag.',

            // Normal Prabhag Department
            'prabhag.*.required' => 'Please select at least one prabhag for each department.',
            'prabhag.*.*.required' => 'Please select a prabhag.',
            'prabhagward.*.required' => 'Please select at least one ward for each prabhag.',
            'prabhagward.*.*.required' => 'Please select a ward for the selected prabhag.',

            // General Departments
            'wards.*.required' => 'Please select at least one ward for each department.',
            'wards.*.*.required' => 'Please select a ward.',
        ];
    }

    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            $roleId = $this->input('role');
            $roleName = Role::find($roleId)->name ?? 'Unknown Role';
            $duplicateItems = []; // collect all duplicates

            // Iterate through the selected departments
            $departments = $this->input('departments', []);
            foreach ($departments as $index => $departmentId) {
                $departmentName = Department::find($departmentId)->name ?? 'Unknown Department';

                // Handle the Water Department (ID: 5)
                if ($departmentId == 5) {
                    $prabhags = (array) ($this->input("water_prabhag.$index") ?? []);
                    $wards = (array) ($this->input("prabhagward.$index") ?? []);

                    foreach ($prabhags as $prabhagId) {
                        $waterPrabhagName = WaterPrabhag::find($prabhagId)->name ?? $prabhagId;
                        foreach ($wards as $wardId) {
                            $wardName = WaterPrabhagWards::find($wardId)->ward_name ?? $wardId;

                            // Check for existing user with the same role, prabhag, and ward
                            $exists = DepartmentUser::where('department_id', $departmentId)
                                ->where('prabhag', $prabhagId)
                                ->where('ward_name', $wardId)
                                ->whereHas('user.roles', fn($q) => $q->where('roles.id', $roleId))
                                ->where('user_id', '!=', $this->route('user')->id)
                                ->exists();

                            if ($exists) {
                                $duplicateItems[] = "({$departmentName}, {$waterPrabhagName} - Ward: {$wardName})";
                            }
                        }
                    }
                }

                // Handle the Normal Prabhag Department (ID: 4)
                elseif ($departmentId == 4) {
                    $prabhags = (array) ($this->input("prabhag.$index") ?? []);
                    $wards = (array) ($this->input("prabhagward.$index") ?? []);

                    foreach ($prabhags as $prabhagId) {
                        $prabhagName = Prabhag::find($prabhagId)->name ?? $prabhagId;
                        foreach ($wards as $wardId) {
                            $wardName = PrabhagWard::find($wardId)->ward_name ?? $wardId;

                            // Check for existing user with the same role, prabhag, and ward
                            $exists = DepartmentUser::where('department_id', $departmentId)
                                ->where('prabhag', $prabhagId)
                                ->where('ward_name', $wardId)
                                ->whereHas('user.roles', fn($q) => $q->where('roles.id', $roleId))
                                ->where('user_id', '!=', $this->route('user')->id)
                                ->exists();

                            if ($exists) {
                                $duplicateItems[] = "({$departmentName}, Prabhag: {$prabhagName} - Ward: {$wardName})";
                            }
                        }
                    }
                }

                // Handle General Departments (other than Water and Prabhag)
                else {
                    $wards = (array) ($this->input("wards.$index") ?? []);
                    foreach ($wards as $wardId) {
                        $wardName = Ward::find($wardId)->name ?? $wardId;

                        // Check for existing user with the same role and ward
                        $exists = DepartmentUser::where('department_id', $departmentId)
                            ->where('ward_name', $wardId)
                            ->whereHas('user.roles', fn($q) => $q->where('roles.id', $roleId))
                            ->where('user_id', '!=', $this->route('user')->id)
                            ->exists();

                        if ($exists) {
                            $duplicateItems[] = "({$departmentName} - Ward: {$wardName})";
                        }
                    }
                }
            }

            // Add a single message if duplicates exist
            if (!empty($duplicateItems)) {
                $message = "User with role '{$roleName}' is already assigned to: "
                            . implode(', ', $duplicateItems) . ".";
                $validator->errors()->add('duplicate_ward_edit', $message);
            }
        });
    }
}
