<?php

namespace App\Http\Controllers;

use App\Models\Tier;
use App\Models\User;
use Illuminate\Http\Request;
use App\Models\TierPermissions;
use App\Models\EmpPersonalDetails;
use App\Models\PermissionsModules;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Models\EmpCompanyDetails;
use Illuminate\Support\Facades\Auth;
use Intervention\Image\ImageManager;
use App\Models\PermissionsSubModules;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class PermissionsController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $userTable = $this->getUserTable();
        $auth_id =0;
        $workspace_id = 0;
        if(Auth::user()->user_type == 1){

            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;
            $tiers = Tier::where('customer_id', $auth_id)->where('workspace_id', $workspace_id);
            if($request->filled('pagination') || !empty($request->filters)){
                $tiers = $this->searchFilterRecord($tiers, $request);
            }else{
                $tiers = $tiers->get();
            }
            if ($tiers->isEmpty()) return $this->error('Tiers not found');

            $empCompanyDetails = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->select('id', 'tier_id', 'employee_email')
                ->get();
            if ($empCompanyDetails->isEmpty()) return $this->message('No employees found', 404);

            $employeeIds = $empCompanyDetails->pluck('id')->toArray();
            $personalDetails = EmpPersonalDetails::whereIn('emp_id', $employeeIds)
                ->select('id', 'emp_id', 'first_name', 'middle_name', 'last_name', 'image')
                ->get();
            if ($personalDetails->isEmpty()) return $this->message('No user details found', 404);

            $empDetailsMap = $personalDetails->keyBy('emp_id')->toArray();
            $empCompanyMap = $empCompanyDetails->keyBy('id')->toArray();

            $usersByTier = [];
            foreach ($empCompanyDetails as $emp) {
                if ($emp->tier_id) {
                    if (!isset($usersByTier[$emp->tier_id])) $usersByTier[$emp->tier_id] = [];
                    
                    // Initialize userData with default values
                    $userData = [
                        'id' => null,
                        'emp_id' => $emp->id,
                        'first_name' => $empCompanyMap[$emp->id]['employee_email'],
                        'middle_name' => null,
                        'last_name' => null,
                        'image' => 'upload/images/default.png'
                    ];
                    
                    // If personal details exist, merge them with default values
                    if (isset($empDetailsMap[$emp->id])) {
                        $userData = array_merge($userData, $empDetailsMap[$emp->id]);
                    }
                    
                    $userData['tier_id'] = $emp->tier_id;
                    $usersByTier[$emp->tier_id][] = $userData;
                }
            }

            $data['tiers'] = $tiers->map(function ($tier) use ($usersByTier) {
                $tierData = $tier->toArray();
                $tierData['users'] = $usersByTier[$tier->id] ?? [];
                return $tierData;
            });

            if ($data['tiers']->isEmpty()) return $this->message('Data not found', 404);

           }else{

            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;  
                $authPersonalDetails = User::where('id', Auth::user()->id)->first();
                
            }
            if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
                $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();  
            }
    
            $tiers = Tier::where('customer_id', $auth_id)->where('workspace_id', $workspace_id);
            if($request->filled('pagination') || !empty($request->filters)){
                $tiers = $this->searchFilterRecord($tiers, $request);
            }else{
                $tiers = $tiers->get();
            }
            if ($tiers->isEmpty()) return $this->error('Tiers not found');

            $empCompanyDetails = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->select('id', 'tier_id', 'employee_email')
                ->get();
            if ($empCompanyDetails->isEmpty()) return $this->message('No employees found', 404);

            $employeeIds = $empCompanyDetails->pluck('id')->toArray();
            
            $personalDetails = EmpPersonalDetails::whereIn('emp_id', $employeeIds)
                ->select('id', 'emp_id', 'first_name', 'middle_name', 'last_name', 'image')
                ->get();
                
            if ($personalDetails->isEmpty()) return $this->message('No user details found', 404);

            $empDetailsMap = $personalDetails->keyBy('emp_id')->toArray();
            $empCompanyMap = $empCompanyDetails->keyBy('id')->toArray();

            $usersByTier = [];
            foreach ($empCompanyDetails as $emp) {
                if ($emp->tier_id) {
                    if (!isset($usersByTier[$emp->tier_id])) $usersByTier[$emp->tier_id] = [];
                    
                    // Initialize userData with default values
                    $userData = [
                        'id' => null,
                        'emp_id' => $emp->id,
                        'first_name' => $empCompanyMap[$emp->id]['employee_email'],
                        'middle_name' => null,
                        'last_name' => null,
                        'image' => 'upload/images/default.png'
                    ];
                    
                    // If personal details exist, merge them with default values
                    if (isset($empDetailsMap[$emp->id])) {
                        $userData = array_merge($userData, $empDetailsMap[$emp->id]);
                    }
                    
                    $userData['tier_id'] = $emp->tier_id;
                    $usersByTier[$emp->tier_id][] = $userData;
                }
            }

            // Check if tiers is paginated and preserve pagination structure
            if (method_exists($tiers, 'getCollection')) {
                // If paginated, map the collection and preserve pagination
                $mappedCollection = $tiers->getCollection()->map(function ($tier) use ($usersByTier) {
                    $tierData = $tier->toArray();
                    $tierData['users'] = $usersByTier[$tier->id] ?? [];
                    return $tierData;
                });
                
                // Set the mapped collection back to preserve pagination
                $tiers->setCollection($mappedCollection);
                $data['tiers'] = $tiers;
            } else {
                // If not paginated, just map normally
                $data['tiers'] = $tiers->map(function ($tier) use ($usersByTier) {
                    $tierData = $tier->toArray();
                    $tierData['users'] = $usersByTier[$tier->id] ?? [];
                    return $tierData;
                });
            }

            if ($data['tiers']->isEmpty()) return $this->message('Data not found', 404);
        }
      
   
        return $this->success($data,'Tiers and Permission module get successfully');
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'tier_id' => 'nullable|integer|exists:tiers,id', 
            'modules' => 'nullable|array', 
            'modules.*.module_id' => 'nullable|integer|exists:permissions_modules,id',
            'modules.*.view' => 'nullable|boolean',
            'modules.*.maintain' => 'nullable|boolean',
            'modules.*.submodules' => 'nullable|array',
            'modules.*.submodules.*.sub_module_id' => 'nullable|integer|exists:permissions_sub_modules,id', 
            'modules.*.submodules.*.view' => 'nullable|boolean',
            'modules.*.submodules.*.maintain' => 'nullable|boolean', 
        ]);
    
        $modules = $validatedData['modules'];
        $permissionsToInsert = [];
    
        foreach ($modules as $module) {
            // Add module permissions
            $permissionsToInsert[] = [
                'tier_id' => $validatedData['tier_id'],
                'module_id' => $module['module_id'],
                'sub_module_id' => null,
                'view' => $module['view'],
                'maintain' => $module['maintain'],
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ];

            // Add submodule permissions if they exist
            if (isset($module['submodules']) && is_array($module['submodules'])) {
                foreach ($module['submodules'] as $submodule) {
                    $permissionsToInsert[] = [
                        'tier_id' => $validatedData['tier_id'],
                        'module_id' => null,
                        'sub_module_id' => $submodule['sub_module_id'],
                        'view' => $submodule['view'],
                        'maintain' => $submodule['maintain'],
                        'created_at' => Carbon::now(),
                        'updated_at' => Carbon::now()
                    ];
                }
            }
        }
    
        TierPermissions::where('tier_id', $validatedData['tier_id'])->delete();
    
        TierPermissions::insert($permissionsToInsert);
    
        return response()->json([
            'message' => 'Permissions Saved Successfully'
        ], 200);
    }
    

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }
    public function addPermissionModule(Request $request)
    {
        $auth_id = Auth::id();
        $workspace_id = Auth::user()->current_workspace_id;
    
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255',
            'submodules' => 'nullable|array',
            'submodules.*.title' => 'nullable|string|max:255',
            'priority' => [
                'nullable',
                'integer',
                Rule::unique('permissions_modules')
                    ->where(function ($query) use ($auth_id, $workspace_id) {
                        return $query->where('customer_id', $auth_id)
                                    ->where('workspace_id', $workspace_id);
                    })
            ],
        ]);
    
        if ($validator->fails()) {
            return response()->json([
                'status' => 'error',
                'errors' => $validator->errors()
            ], 422);
        }
    
        $validatedData = $validator->validated();
    
        $priority = $validatedData['priority'] ?? null;
    
        // Handle module image
        $moduleImage = $this->handleFileImageUpload($request, 'module');
        $moduleImagePath = $moduleImage['path'] ?? null;
        
        $module = PermissionsModules::create([
            'title' => $validatedData['title'],
            'priority' => $priority,
            'image' => $moduleImagePath,
            'link' => $request->link,
            'customer_id' => $auth_id,
            'workspace_id' => $workspace_id,
            'del' => '0',
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    
        // Handle submodules with image upload
        $submodulesData = [];
        if (!empty($validatedData['submodules'])) {
            foreach ($validatedData['submodules'] as $index => $submodule) {
                $submoduleRequest = new Request();
                $submoduleRequest->files->set('submodule', $request->file("submodules.$index.image"));
                $subImage = $this->handleFileImageUpload($submoduleRequest, 'submodule');
                $subImagePath = $subImage['path'] ?? null;
    
                $submodulesData[] = [
                    'title' => $submodule['title'],
                    'module_id' => $module->id,
                    'link' => $submodule['link'],
                    'priority' => $submodule['priority'],
                    'image' => $subImagePath,
                    'del' => '0',
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
    
            PermissionsSubModules::insert($submodulesData);
        }
    
        return response()->json([
            'module' => $module,
            'submodules' => $submodulesData
        ], 200);
    }
    
    
    public function updatePermissionModule(Request $request, $id)
    {
        $auth_id = Auth::id();
        $workspace_id = Auth::user()->current_workspace_id;
    
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255',
            'submodules' => 'nullable|array',
            'submodules.*.id' => 'nullable|integer|exists:permissions_sub_modules,id',
            'submodules.*.title' => 'nullable|string|max:255',
            'submodules.*.link' => 'nullable|string',
            'submodules.*.priority' => 'nullable|integer',
            'priority' => [
                'nullable',
                'integer',
                Rule::unique('permissions_modules')
                    ->where(function ($query) use ($auth_id, $workspace_id) {
                        return $query->where('customer_id', $auth_id)
                                    ->where('workspace_id', $workspace_id);
                    })
                    ->ignore($id)
            ],
        ]);
    
        if ($validator->fails()) {
            return response()->json([
                'status' => 'error',
                'errors' => $validator->errors()
            ], 422);
        }
    
        $validatedData = $validator->validated();
        $module = PermissionsModules::find($id);
    
        if (!$module) {
            return response()->json(['message' => 'Module not found'], 404);
        }
    
        $moduleImagePath = $module->image; // Keep existing image by default
        if ($request->hasFile('module')) {
            $moduleImage = $this->handleFileImageUpload($request, 'module', $module->image);
            $moduleImagePath = $moduleImage['path'] ?? $module->image;
        }
    
        $priority = $validatedData['priority'] ?? $module->priority; // Keep existing priority if not provided
    
        $module->update([
            'title' => $validatedData['title'],
            'priority' => $priority,
            'link' => $request->link ?? $module->link,
            'customer_id' => $auth_id,
            'workspace_id' => $workspace_id,
            'image' => $moduleImagePath,
            'updated_at' => now(),
        ]);
    
        // Get existing submodules
        $existingSubmodules = PermissionsSubModules::where('module_id', $id)->get()->keyBy('id');
        $updatedSubmoduleIds = [];
        
        if (!empty($validatedData['submodules'])) {
            foreach ($validatedData['submodules'] as $index => $submodule) {
                $subImagePath = null;
                if ($request->hasFile("submodules.$index.image")) {
                    $submoduleRequest = new Request();
                    $submoduleRequest->files->set('submodule', $request->file("submodules.$index.image"));
                    $subImage = $this->handleFileImageUpload($submoduleRequest, 'submodule');
                    $subImagePath = $subImage['path'] ?? null;
                }

                $submoduleData = [
                    'title' => $submodule['title'],
                    'module_id' => $module->id,
                    'link' => $submodule['link'] ?? null,
                    'priority' => $submodule['priority'] ?? null,
                    'del' => '0',
                    'updated_at' => now(),
                ];

                if ($subImagePath) {
                    $submoduleData['image'] = $subImagePath;
                }

                if (isset($submodule['id']) && $existingSubmodules->has($submodule['id'])) {
                    // Update existing submodule
                    PermissionsSubModules::where('id', $submodule['id'])->update($submoduleData);
                    $updatedSubmoduleIds[] = $submodule['id'];
                } else {
                    // Create new submodule
                    $submoduleData['created_at'] = now();
                    $newSubmodule = PermissionsSubModules::create($submoduleData);
                    $updatedSubmoduleIds[] = $newSubmodule->id;
                }
            }
        }

        // Delete submodules that were not included in the update
        PermissionsSubModules::where('module_id', $id)
            ->whereNotIn('id', $updatedSubmoduleIds)
            ->delete();
    
        // Get updated submodules for response
        $updatedSubmodules = PermissionsSubModules::where('module_id', $id)->get();
    
        return response()->json([
            'status' => 'success',
            'message' => 'Permission module updated successfully',
            'module' => $module,
            'submodules' => $updatedSubmodules
        ], 200);
    }
    

    public function deletePermissionModule($id) {
        $module = PermissionsModules::find($id);
        
        if ($module) {
            PermissionsSubModules::where('module_id', $id)->delete();
            $module->delete();
            return response()->json(['message' => 'Module and submodules deleted successfully'], 200);
        }
        
        $subModule = PermissionsSubModules::find($id);
        
        if ($subModule) {
            $subModule->delete();
            return response()->json(['message' => 'Submodule deleted successfully'], 200);
        }
        
        return response()->json(['message' => 'No module or submodule found with the given ID'], 404);
    }

    public function getAllModules(Request $request)
    {
        $auth_id = Auth::user()->id;
        $workspace_id = Auth::user()->current_workspace_id;
    
        // Build base query for modules
        $modulesQuery = PermissionsModules::where('customer_id', $auth_id)
            ->where('workspace_id', $workspace_id);
    
        // Add search functionality if search parameter is provided
        if ($request->filled('search')) {
            $search = $request->input('search');
            
            // Find submodules that match the search term
            $matchingSubmoduleIds = PermissionsSubModules::where('title', 'like', '%' . $search . '%')
                ->pluck('module_id')
                ->unique()
                ->toArray();
            
            // Query modules that either match the search OR have submodules that match
            $modulesQuery->where(function($query) use ($search, $matchingSubmoduleIds) {
                $query->where('title', 'like', '%' . $search . '%');
                
                // Also include modules that have matching submodules
                if (!empty($matchingSubmoduleIds)) {
                    $query->orWhereIn('id', $matchingSubmoduleIds);
                }
            });
        }
    
        // Sort by priority (NULL values at the end)
        $modulesQuery->orderByRaw('COALESCE(priority, 999999) ASC');
    
    
        // Get the collection (either from paginator or direct collection)
        $modulesCollection = $modulesQuery->get();
    
        // Attach submodules to each module
        // Note: When searching, we include modules that match OR have matching submodules,
        // but we always return ALL submodules of the matched modules
        foreach ($modulesCollection as $module) {
            $submodules = PermissionsSubModules::where('module_id', $module->id)->get();
            $module->submodules = $submodules;
        }
    
        // Return non-paginated response (same structure as before)
        return $this->success($modulesCollection->values()->toArray(), 'Modules fetched successfully');
    }
    

    public function getModuleById($id)
    {
        $module = PermissionsModules::find($id);

        if (!$module) {
            return response()->json(['message' => 'Module not found'], 404);
        }

        $submodules = PermissionsSubModules::where('module_id', $id)->get();

        return response()->json([
            'module' => $module,
            'submodules' => $submodules
        ], 200);
    }
    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}
