<?php

namespace App\Http\Controllers;

use DB;
use App\Models\Role;
use App\Models\Tier;
use App\Models\User;
use Illuminate\Http\Request;
use App\Models\TierPermissions;
use Illuminate\Validation\Rule;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use App\Models\PermissionsModules;
use App\Models\PermissionsSubModules;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;



class RoleController extends Controller
{

    public function index(Request $request)
    {
        $roles = Role::where('del', '0')->get();
        return $this->success($roles, 'Get Roles Successfully');
    }

    public function show($id)
    {
        $role = Role::where('id', $id)
            ->where('del', '0')
            ->first();

        if (!$role) {
            return $this->notFound('Role not found', 404);
        }

        return $this->success($role, 'Get Role Details Successfully');
    }

    public function role_edit(Request $request)
    {
        $id = $request->id;
        $role = Role::where('id', $id)
            ->where('del', '0')
            ->first();

        if (!$role) {
            return $this->notFound('Role not found', 404);
        }

        return $this->success($role, 'Get Role Details Successfully');
    }

    public function role_update(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required',
            'id' => 'required',
            'code' => 'required',
        ]);
    
        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }

        $id = $request->id;
        $validatedData = $validator->validated();
        
        // Normalize code to uppercase
        if (isset($validatedData['code'])) {
            $validatedData['code'] = strtoupper($validatedData['code']);
        }
        
        $role = Role::where('id', $id)
            ->where('del', '0')
            ->first();
    
        if (!$role) {
            return $this->notFound('Role Not Found', 404);
        }
        
        // Check if another role with same code exists (excluding current one)
        $existingRole = Role::where('code', $validatedData['code'])
            ->where('id', '!=', $id)
            ->where('del', '0')
            ->first();
    
        if ($existingRole) {
            return $this->error('This code is already taken', 400);
        }
        
        $role->update($validatedData);
    
        $data['roles'] = Role::where('del', '0')->get();
        
        return $this->success($data, 'Role Updated Successfully');
    }
    


    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required',
            'code' => 'required|unique:roles,code,NULL,id,del,0',
        ]);
    
        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }

        $validatedData = $validator->validated();
        
        // Normalize code to uppercase
        if (isset($validatedData['code'])) {
            $validatedData['code'] = strtoupper($validatedData['code']);
        }
        
        // Set default del value
        if (!isset($validatedData['del'])) {
            $validatedData['del'] = '0';
        }
    
        $role = Role::create($validatedData);
        
        $data['roles'] = Role::where('del', '0')->get();

        return $this->success($data, 'Role Saved Successfully');
    }
    


    public function role_delete(Request $request)
    {
        $id = $request->id;
        $role = Role::where('id', $id)
            ->where('del', '0')
            ->first();
            
        if (!$role) {
            return $this->notFound('Role not found', 404);
        }

        // Check if role is being used by any employees
        $employeesUsingRole = \App\Models\EmpCompanyDetails::where('access_role', $role->code)
            ->where('del', '0')
            ->count();
            
        if ($employeesUsingRole > 0) {
            return $this->error('Cannot delete role. It is being used by ' . $employeesUsingRole . ' employee(s).', 422);
        }

        $role->update(['del' => '1']);
        
        return $this->message('Role Deleted Successfully', 200);
    }


    
    public function tierRelatedData(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'tier_id' => 'required'
        ]);
    
        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {
            $validatedData = $validator->validated();
            $userTable = $this->getUserTable();
            $auth_id = 0;
            $workspace_id = 0;
            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();
            }
    
            $tier = Tier::where('id', $validatedData['tier_id'])
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->first();
            if (!$tier) return $this->error('Tier not found');
    
            $tierPermissions = TierPermissions::where('tier_id', $validatedData['tier_id'])
                ->where('del', '0')
                ->get();
    
            $modulePermissions = $tierPermissions->whereNull('sub_module_id')->groupBy('module_id')->toArray();
    
            $subModulePermissions = $tierPermissions->whereNotNull('sub_module_id');
            $permissionSubModuleIds = $subModulePermissions->pluck('sub_module_id')->unique()->toArray();
    
            $permissionSubModules = PermissionsSubModules::whereIn('id', $permissionSubModuleIds)
                ->where('del', '0')
                ->get();
    
            $moduleIds = $permissionSubModules->pluck('module_id')->unique()->toArray();
            $permissionModuleIds = $tierPermissions->pluck('module_id')->unique()->toArray();
            $allModuleIds = array_unique(array_merge($moduleIds, $permissionModuleIds));
    
            $permissionModules = PermissionsModules::whereIn('id', $allModuleIds)
                ->where('del', '0')
                ->get();
    
            $referenceModule = $permissionModules->first();
            $customer_id = $referenceModule->customer_id ?? $auth_id;
            $workspace_id = $referenceModule->workspace_id ?? $workspace_id;
    
            $allModules = PermissionsModules::where('del', '0')
                ->where(function ($query) use ($customer_id) {
                    $query->where('customer_id', $customer_id)
                        ->orWhereNull('customer_id');
                })
                ->where(function ($query) use ($workspace_id) {
                    $query->where('workspace_id', $workspace_id)
                        ->orWhereNull('workspace_id');
                })
                ->get();
    
            $allModuleIds = $allModules->pluck('id')->toArray();
            $allSubModules = PermissionsSubModules::whereIn('module_id', $allModuleIds)
                ->where('del', '0')
                ->get();
    
            // Group permissions by submodule ID
            $permissionsBySubModule = [];
            foreach ($subModulePermissions as $perm) {
                $subModId = $perm->sub_module_id;
                if (!isset($permissionsBySubModule[$subModId])) $permissionsBySubModule[$subModId] = [];
                $permissionsBySubModule[$subModId][] = $perm->toArray();
            }
    
            // Group submodules by module ID
            $subModulesByModule = [];
            foreach ($allSubModules as $subMod) {
                $modId = $subMod->module_id;
                if (!isset($subModulesByModule[$modId])) $subModulesByModule[$modId] = [];
    
                $subModData = $subMod->toArray();
                $subModData['permissions'] = $permissionsBySubModule[$subMod->id] ?? [];
                $subModulesByModule[$modId][] = $subModData;
            }
    
            $moduleData = [];
            foreach ($allModules as $mod) {
                $modInfo = $mod->toArray();
                
                // Add module-level permissions
                $modPermissions = collect($tierPermissions)
                    ->where('module_id', $mod->id)
                    ->whereNull('sub_module_id')
                    ->first();
                    
                $modInfo['view'] = $modPermissions ? $modPermissions->view : 0;
                $modInfo['maintain'] = $modPermissions ? $modPermissions->maintain : 0;
                $modInfo['sub_modules'] = $subModulesByModule[$mod->id] ?? [];
                $moduleData[] = $modInfo;
            }
    
            $data = ['tier' => $tier, 'modules' => $moduleData];

            if (empty($data['modules'])) {
                $allModules = PermissionsModules::where('del', '0')
                    ->where(function ($query) use ($auth_id) {
                        $query->where('customer_id', 11)
                            ->orWhereNull('customer_id');
                    })
                    ->where(function ($query) use ($workspace_id) {
                        $query->where('workspace_id', 1)
                            ->orWhereNull('workspace_id');
                    })
                    ->get();

                $allModuleIds = $allModules->pluck('id')->toArray();
                $allSubModules = PermissionsSubModules::whereIn('module_id', $allModuleIds)
                    ->where('del', '0')
                    ->get();

                $subModulesByModule = [];
                foreach ($allSubModules as $subMod) {
                    $modId = $subMod->module_id;
                    if (!isset($subModulesByModule[$modId])) $subModulesByModule[$modId] = [];

                    $subModData = $subMod->toArray();
                    $subModData['permissions'] = [];
                    $subModulesByModule[$modId][] = $subModData;
                }

                $defaultModuleData = [];
                foreach ($allModules as $mod) {
                    $modInfo = $mod->toArray();
                    $modInfo['view'] = 0;
                    $modInfo['maintain'] = 0;
                    $modInfo['sub_modules'] = $subModulesByModule[$mod->id] ?? [];
                    $defaultModuleData[] = $modInfo;
                }

                $data = ['tier' => $tier, 'modules' => $defaultModuleData];
            }

            return $this->success($data, 'Get Tier Related Data Successfully');
        }
    }

}
