<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Illuminate\Support\Facades\DB;

class RoleController extends Controller
{
    public function index(Request $request)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');

        $query = Role::with('permissions');

        // If not super admin, only show roles for their company
        if (!$isSuperAdmin && $user->company_id) {
            $query->where(function ($q) use ($user) {
                $q->where('company_id', $user->company_id)
                  ->orWhereNull('company_id');
            });
        }

        $roles = $query->get()->map(function ($role) {
            $role->users_count = \DB::table('model_has_roles')
                ->where('role_id', $role->id)
                ->count();
            return $role;
        });

        return response()->json([
            'data' => $roles,
            'message' => 'Roles retrieved successfully'
        ]);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');

        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:roles,name',
            'description' => 'nullable|string',
            'permissions' => 'array',
            'permissions.*' => 'exists:permissions,id',
            'company_id' => 'nullable|exists:companies,id',
        ]);

        // Non-super admins can only create company-specific roles
        if (!$isSuperAdmin) {
            if (!$user->company_id) {
                return response()->json(['message' => 'You must be associated with a company'], 403);
            }
            $validated['company_id'] = $user->company_id;
        }

        DB::beginTransaction();
        try {
            $role = Role::create([
                'name' => $validated['name'],
                'guard_name' => 'web',
                'company_id' => $validated['company_id'] ?? null,
            ]);

            if (isset($validated['permissions'])) {
                $permissions = Permission::whereIn('id', $validated['permissions'])->get();
                $role->syncPermissions($permissions);
            }

            activity()
                ->performedOn($role)
                ->causedBy($user)
                ->log('Created role: ' . $role->name);

            DB::commit();

            return response()->json([
                'data' => $role->load('permissions'),
                'message' => 'Role created successfully'
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['message' => 'Error creating role: ' . $e->getMessage()], 500);
        }
    }

    public function update(Request $request, $id)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');
        
        $role = Role::findOrFail($id);

        // Check permissions
        if (!$isSuperAdmin) {
            if ($role->company_id !== $user->company_id) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }

        // Prevent editing Super Admin role
        if ($role->name === 'Super Admin') {
            return response()->json(['message' => 'Cannot edit Super Admin role'], 403);
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:roles,name,' . $id,
            'description' => 'nullable|string',
            'permissions' => 'array',
            'permissions.*' => 'exists:permissions,id',
        ]);

        DB::beginTransaction();
        try {
            $role->update([
                'name' => $validated['name'],
            ]);

            if (isset($validated['permissions'])) {
                $permissions = Permission::whereIn('id', $validated['permissions'])->get();
                $role->syncPermissions($permissions);
            }

            activity()
                ->performedOn($role)
                ->causedBy($user)
                ->log('Updated role: ' . $role->name);

            DB::commit();

            return response()->json([
                'data' => $role->load('permissions'),
                'message' => 'Role updated successfully'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['message' => 'Error updating role: ' . $e->getMessage()], 500);
        }
    }

    public function destroy(Request $request, $id)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');
        
        $role = Role::findOrFail($id);

        // Check permissions
        if (!$isSuperAdmin) {
            if ($role->company_id !== $user->company_id) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }

        // Prevent deleting Super Admin role
        if ($role->name === 'Super Admin') {
            return response()->json(['message' => 'Cannot delete Super Admin role'], 403);
        }

        // Check if role has users
        if ($role->users()->count() > 0) {
            return response()->json(['message' => 'Cannot delete role with assigned users'], 400);
        }

        activity()
            ->performedOn($role)
            ->causedBy($user)
            ->log('Deleted role: ' . $role->name);

        $role->delete();

        return response()->json(['message' => 'Role deleted successfully']);
    }

    public function assignRole(Request $request)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');

        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'role_id' => 'required|exists:roles,id',
        ]);

        $targetUser = \App\Models\User::findOrFail($validated['user_id']);
        $role = Role::findOrFail($validated['role_id']);

        // Non-super admins can only assign roles within their company
        if (!$isSuperAdmin) {
            if ($targetUser->company_id !== $user->company_id || 
                ($role->company_id && $role->company_id !== $user->company_id)) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }

        $targetUser->assignRole($role);

        activity()
            ->performedOn($targetUser)
            ->causedBy($user)
            ->log("Assigned role '{$role->name}' to user");

        return response()->json(['message' => 'Role assigned successfully']);
    }

    public function revokeRole(Request $request)
    {
        $user = $request->user();
        $isSuperAdmin = $user->hasRole('Super Admin');

        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'role_id' => 'required|exists:roles,id',
        ]);

        $targetUser = \App\Models\User::findOrFail($validated['user_id']);
        $role = Role::findOrFail($validated['role_id']);

        // Non-super admins can only revoke roles within their company
        if (!$isSuperAdmin) {
            if ($targetUser->company_id !== $user->company_id) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }

        // Prevent revoking Super Admin
        if ($role->name === 'Super Admin') {
            return response()->json(['message' => 'Cannot revoke Super Admin role'], 403);
        }

        $targetUser->removeRole($role);

        activity()
            ->performedOn($targetUser)
            ->causedBy($user)
            ->log("Revoked role '{$role->name}' from user");

        return response()->json(['message' => 'Role revoked successfully']);
    }
}
