<?php

namespace Modules\PurchaseRequisition\Entities\Services;

use App\BusinessLocation;
use Illuminate\Support\Collection;
use DB;

class LocationService
{
    /**
     * Get accessible locations for user based on permissions.
     *
     * @param int $businessId
     * @param string $status (generate|index|approve)
     * @param string $direction (from|to)
     * @param int|null $userId
     * @return Collection
     */
    public function accessLocationsForUser($businessId, $status, $direction, $userId = null)
    {
        $user = $userId ? \App\User::find($userId) : auth()->user();

        if (!$user) {
            return collect([]);
        }

        $query = BusinessLocation::where('business_id', $businessId);

        // Check permissions in order: all > his > selected
        $allPermission = "purchase_requisition.location_access_{$status}_{$direction}_all_locations";
        $hisPermission = "purchase_requisition.location_access_{$status}_{$direction}_his_locations";
        $selectedPermission = "purchase_requisition.location_access_{$status}_{$direction}_selected_locations";

        // If user can access all locations
        if ($user->can($allPermission)) {
            return $query->get();
        }

        // If user can access his permitted locations
        if ($user->can($hisPermission)) {
            $permittedLocations = $user->permitted_locations();
            if ($permittedLocations && is_array($permittedLocations)) {
                $query->whereIn('business_locations.id', $permittedLocations);
                return $query->get();
            }
        }

        // If user can access selected locations
        if ($user->can($selectedPermission)) {
            $type = $status . '_' . $direction;
            $locationIds = DB::table('pr_user_locations')
                ->where('business_id', $businessId)
                ->where('user_id', $user->id)
                ->where('type', $type)
                ->pluck('location_id');

            if ($locationIds->isNotEmpty()) {
                $query->whereIn('business_locations.id', $locationIds);
                return $query->get();
            }
        }

        // No permission, return empty collection
        return collect([]);
    }

    /**
     * Get accessible locations for dropdown.
     *
     * @param int $businessId
     * @param string $status
     * @param string $direction
     * @param int|null $userId
     * @param bool $prependAll
     * @return array
     */
    public function accessLocationsForUserForDropdown($businessId, $status, $direction, $userId = null, $prependAll = false)
    {
        $locations = $this->accessLocationsForUser($businessId, $status, $direction, $userId);

        $dropdown = $locations->pluck('name', 'id')->toArray();

        if ($prependAll) {
            $dropdown = ['' => __('purchaseRequisition::lang.all')] + $dropdown;
        }

        return $dropdown;
    }

    /**
     * Check if user has access to a specific location.
     *
     * @param int $businessId
     * @param int $locationId
     * @param string $status
     * @param string $direction
     * @param int|null $userId
     * @return bool
     */
    public function hasAccessToLocation($businessId, $locationId, $status, $direction, $userId = null)
    {
        $accessibleLocations = $this->accessLocationsForUser($businessId, $status, $direction, $userId);

        return $accessibleLocations->contains('id', $locationId);
    }

    /**
     * Save user location permissions.
     *
     * @param int $userId
     * @param int $businessId
     * @param string $type (generate_from|generate_to|index_from|index_to|approve_from|approve_to)
     * @param array $locationIds
     * @return bool
     */
    public function saveUserLocationPermissions($userId, $businessId, $type, array $locationIds)
    {
        // Delete existing permissions for this type
        DB::table('pr_user_locations')
            ->where('user_id', $userId)
            ->where('business_id', $businessId)
            ->where('type', $type)
            ->delete();

        // Insert new permissions
        $data = [];
        foreach ($locationIds as $locationId) {
            $data[] = [
                'user_id' => $userId,
                'business_id' => $businessId,
                'type' => $type,
                'location_id' => $locationId,
                'created_at' => now(),
                'updated_at' => now(),
            ];
        }

        if (!empty($data)) {
            DB::table('pr_user_locations')->insert($data);
        }

        return true;
    }

    /**
     * Get user location permissions.
     *
     * @param int $userId
     * @param int $businessId
     * @param string $type
     * @return array
     */
    public function getUserLocationPermissions($userId, $businessId, $type)
    {
        return DB::table('pr_user_locations')
            ->where('user_id', $userId)
            ->where('business_id', $businessId)
            ->where('type', $type)
            ->pluck('location_id')
            ->toArray();
    }
}
