<?php

namespace App\Policies\Disk;

use App\Models\Disk\DiskFolder;
use App\Models\User;

class DiskFolderPolicy
{
    /**
     * Determine if user can view any folders.
     */
    public function viewAny(User $user): bool
    {
        return $user->hasAgency() && $user->hasAnyRole(['agency-owner', 'agency-manager', 'agency-staff']);
    }

    /**
     * Determine if user can view the folder.
     */
    public function view(User $user, DiskFolder $folder): bool
    {
        // Super admin can view everything
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // If folder is public, allow access
        if ($folder->is_public) {
            return true;
        }

        // Check custom permissions
        if ($folder->permissions && is_array($folder->permissions)) {
            // Check role-based permissions
            if (isset($folder->permissions['view_roles'])) {
                if ($user->hasAnyRole($folder->permissions['view_roles'])) {
                    return true;
                }
            }

            // Check user-based permissions
            if (isset($folder->permissions['view_users'])) {
                if (in_array($user->id, $folder->permissions['view_users'])) {
                    return true;
                }
            }
        }

        // Folder creator can always view
        if ($folder->created_by === $user->id) {
            return true;
        }

        // Default: agency owner and manager can view
        return $user->hasAnyRole(['agency-owner', 'agency-manager']);
    }

    /**
     * Determine if user can create folders.
     */
    public function create(User $user): bool
    {
        return $user->hasAgency() && $user->hasAnyRole(['agency-owner', 'agency-manager', 'agency-staff']);
    }

    /**
     * Determine if user can update the folder.
     */
    public function update(User $user, DiskFolder $folder): bool
    {
        // Super admin can update everything
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // Folder creator can always update
        if ($folder->created_by === $user->id) {
            return true;
        }

        // Check custom permissions
        if ($folder->permissions && is_array($folder->permissions)) {
            // Check role-based permissions
            if (isset($folder->permissions['edit_roles'])) {
                if ($user->hasAnyRole($folder->permissions['edit_roles'])) {
                    return true;
                }
            }

            // Check user-based permissions
            if (isset($folder->permissions['edit_users'])) {
                if (in_array($user->id, $folder->permissions['edit_users'])) {
                    return true;
                }
            }
        }

        // Default: agency owner and manager can update
        return $user->hasAnyRole(['agency-owner', 'agency-manager']);
    }

    /**
     * Determine if user can delete the folder.
     */
    public function delete(User $user, DiskFolder $folder): bool
    {
        // Super admin can delete everything
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // Folder creator can delete (unless it's a critical folder)
        if ($folder->created_by === $user->id && !$this->isCriticalFolder($folder)) {
            return true;
        }

        // Only agency owner and manager can delete
        return $user->hasAnyRole(['agency-owner', 'agency-manager']);
    }

    /**
     * Determine if user can restore the folder.
     */
    public function restore(User $user, DiskFolder $folder): bool
    {
        return $this->delete($user, $folder);
    }

    /**
     * Determine if user can permanently delete the folder.
     */
    public function forceDelete(User $user, DiskFolder $folder): bool
    {
        return $user->isSuperAdmin() ||
            ($user->currentAgencyId() === $folder->agency_id && $user->hasRole('agency-owner'));
    }

    /**
     * Determine if user can upload files to the folder.
     */
    public function upload(User $user, DiskFolder $folder): bool
    {
        // Super admin can upload everywhere
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // Folder must be active
        if (!$folder->is_active) {
            return false;
        }

        // Check custom permissions
        if ($folder->permissions && is_array($folder->permissions)) {
            // Check role-based permissions
            if (isset($folder->permissions['upload_roles'])) {
                if ($user->hasAnyRole($folder->permissions['upload_roles'])) {
                    return true;
                }
            }

            // Check user-based permissions
            if (isset($folder->permissions['upload_users'])) {
                if (in_array($user->id, $folder->permissions['upload_users'])) {
                    return true;
                }
            }
        }

        // Folder creator can upload
        if ($folder->created_by === $user->id) {
            return true;
        }

        // All staff members can upload by default
        return $user->hasAnyRole(['agency-owner', 'agency-manager', 'agency-staff']);
    }

    /**
     * Determine if user can manage folder permissions.
     */
    public function managePermissions(User $user, DiskFolder $folder): bool
    {
        // Super admin can manage all permissions
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // Folder creator can manage permissions
        if ($folder->created_by === $user->id) {
            return true;
        }

        // Only agency owner and manager can manage permissions
        return $user->hasAnyRole(['agency-owner', 'agency-manager']);
    }

    /**
     * Determine if user can move files between folders.
     */
    public function moveFiles(User $user, DiskFolder $folder): bool
    {
        return $this->update($user, $folder);
    }

    /**
     * Check if folder is critical (should not be deleted easily).
     */
    private function isCriticalFolder(DiskFolder $folder): bool
    {
        // Root folders or folders with many items are considered critical
        return $folder->level === 0 || $folder->item_count > 50;
    }

    /**
     * Determine if user can view folder statistics.
     */
    public function viewStatistics(User $user, DiskFolder $folder): bool
    {
        return $this->view($user, $folder);
    }

    /**
     * Determine if user can download all files in folder.
     */
    public function downloadAll(User $user, DiskFolder $folder): bool
    {
        // Super admin can download everything
        if ($user->isSuperAdmin()) {
            return true;
        }

        // Same agency check
        if ($user->currentAgencyId() !== $folder->agency_id) {
            return false;
        }

        // Must be able to view the folder
        if (!$this->view($user, $folder)) {
            return false;
        }

        // Agency owner and manager can download all
        return $user->hasAnyRole(['agency-owner', 'agency-manager']);
    }
}
