<?php

namespace App\Http\Traits;

use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;

/**
 * Has Role Views Trait
 *
 * Provides role-based view and route resolution for unified controllers.
 * This trait enables a single controller to serve multiple user roles
 * by automatically resolving views and routes based on the current user's role.
 *
 * Usage:
 *   use HasRoleViews;
 *   return $this->roleView('rfq.index', $data); // Resolves to 'admin.rfq.index' or 'superadmin.rfq.index'
 *   return $this->redirectToRoute('rfq.show', ['id' => 1]); // Resolves route name based on role
 */
trait HasRoleViews
{
    /**
     * Get the current user's role
     */
    protected function getCurrentRole(): string
    {
        $user = Auth::user();

        if (!$user) {
            abort(401, 'Unauthenticated.');
        }

        return strtolower($user->role ?? 'admin');
    }

    /**
     * Resolve view path based on current role
     * Example: 'rfq.index' becomes 'admin.rfq.index' or 'superadmin.rfq.index'
     */
    protected function resolveView(string $view): string
    {
        $role = $this->getCurrentRole();

        // If view already has role prefix, return as is
        if (str_starts_with($view, 'admin.') ||
            str_starts_with($view, 'manager.') ||
            str_starts_with($view, 'superadmin.')) {
            return $view;
        }

        return "{$role}.{$view}";
    }

    /**
     * Resolve route name based on current role
     * Example: 'rfq.index' becomes 'admin.rfq.index' or 'superadmin.rfq.index'
     */
    protected function resolveRoute(string $route): string
    {
        $role = $this->getCurrentRole();

        // If route already has role prefix, return as is
        if (str_starts_with($route, 'admin.') ||
            str_starts_with($route, 'manager.') ||
            str_starts_with($route, 'superadmin.')) {
            return $route;
        }

        return "{$role}.{$route}";
    }

    /**
     * Get route prefix for current role
     */
    protected function getRoutePrefix(): string
    {
        return $this->getCurrentRole();
    }

    /**
     * Get view prefix for current role
     */
    protected function getViewPrefix(): string
    {
        return $this->getCurrentRole();
    }

    /**
     * Redirect to a role-specific route
     */
    protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse
    {
        return redirect()->route($this->resolveRoute($route), $parameters, $status);
    }

    /**
     * Return a role-specific view
     */
    protected function roleView(string $view, array $data = []): View
    {
        return view($this->resolveView($view), $data);
    }

    /**
     * Return a role-specific view with success message
     */
    protected function roleViewWithSuccess(string $view, array $data = [], string $message = 'Operation successful'): View
    {
        return view($this->resolveView($view), array_merge($data, ['success' => $message]));
    }

    /**
     * Redirect back to role-specific route with success message
     */
    protected function redirectBackWithSuccess(string $message = 'Operation successful'): RedirectResponse
    {
        return redirect()->back()->with('success', $message);
    }

    /**
     * Redirect back with error message
     */
    protected function redirectBackWithError(string $message = 'Operation failed'): RedirectResponse
    {
        return redirect()->back()->with('error', $message);
    }

    /**
     * Check if current user can approve (SuperAdmin only by default)
     */
    protected function canApprove(): bool
    {
        return $this->isSuperAdmin();
    }

    /**
     * Abort if user cannot perform action
     */
    protected function authorizeRole(string ...$roles): void
    {
        $currentRole = $this->getCurrentRole();

        if (!in_array($currentRole, array_map('strtolower', $roles))) {
            abort(403, 'Unauthorized action.');
        }
    }

    /**
     * Check if current user has a specific role
     */
    protected function hasRole(string $role): bool
    {
        return $this->getCurrentRole() === strtolower($role);
    }

    /**
     * Check if current user is SuperAdmin
     */
    protected function isSuperAdmin(): bool
    {
        return $this->hasRole('superadmin');
    }

    /**
     * Check if current user is Admin
     */
    protected function isAdmin(): bool
    {
        return $this->hasRole('admin');
    }

    /**
     * Check if current user is Manager
     */
    protected function isManager(): bool
    {
        return $this->hasRole('manager');
    }

    /**
     * Get log prefix for current role
     */
    protected function getLogPrefix(): string
    {
        $roleLabels = [
            'admin' => 'Admin',
            'manager' => 'Manager',
            'superadmin' => 'SuperAdmin',
        ];

        return $roleLabels[$this->getCurrentRole()] ?? 'User';
    }
}
