<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\DeliveryZone;
use App\Services\LocationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class DeliveryZoneController extends Controller
{
    public function __construct(protected LocationService $locationService)
    {
        $this->middleware('auth');
    }

    public function index(): View
    {
        $company = Company::primary() ?? $this->locationService->ensureCompanyAndDefaults();
        $zones = DeliveryZone::query()
            ->where('company_id', $company->id)
            ->with(['locations' => fn ($q) => $q->orderByPivot('priority')])
            ->latest()
            ->paginate(30);
        $stores = $this->locationService->onlineFulfillmentLocations();

        return view('admin.delivery-zones.index', compact('zones', 'stores', 'company'));
    }

    public function store(Request $request): RedirectResponse
    {
        $company = Company::primary() ?? $this->locationService->ensureCompanyAndDefaults();
        $data = $request->validate([
            'name' => 'required|string|max:255',
            'pincode' => 'nullable|string|max:20',
            'pincode_from' => 'nullable|string|max:20',
            'pincode_to' => 'nullable|string|max:20',
            'location_ids' => 'nullable|array',
            'location_ids.*' => 'exists:locations,id',
            'is_active' => 'nullable|boolean',
        ]);

        $zone = DeliveryZone::create([
            'company_id' => $company->id,
            'name' => $data['name'],
            'pincode' => $data['pincode'] ?? null,
            'pincode_from' => $data['pincode_from'] ?? null,
            'pincode_to' => $data['pincode_to'] ?? null,
            'is_active' => $request->boolean('is_active', true),
        ]);

        $zone->locations()->sync($this->syncPayload($data['location_ids'] ?? []));

        return back()->with('success', 'Delivery zone created.');
    }

    public function update(Request $request, DeliveryZone $delivery_zone): RedirectResponse
    {
        $data = $request->validate([
            'name' => 'required|string|max:255',
            'pincode' => 'nullable|string|max:20',
            'pincode_from' => 'nullable|string|max:20',
            'pincode_to' => 'nullable|string|max:20',
            'location_ids' => 'nullable|array',
            'location_ids.*' => 'exists:locations,id',
            'is_active' => 'nullable|boolean',
        ]);

        $delivery_zone->update([
            'name' => $data['name'],
            'pincode' => $data['pincode'] ?? null,
            'pincode_from' => $data['pincode_from'] ?? null,
            'pincode_to' => $data['pincode_to'] ?? null,
            'is_active' => $request->boolean('is_active'),
        ]);

        $delivery_zone->locations()->sync($this->syncPayload($data['location_ids'] ?? []));

        return back()->with('success', 'Delivery zone updated.');
    }

    public function destroy(DeliveryZone $delivery_zone): RedirectResponse
    {
        $delivery_zone->locations()->detach();
        $delivery_zone->delete();

        return back()->with('success', 'Delivery zone deleted.');
    }

    /**
     * @param  array<int, int|string>  $locationIds
     * @return array<int, array{priority: int}>
     */
    protected function syncPayload(array $locationIds): array
    {
        $sync = [];
        foreach (array_values($locationIds) as $i => $locationId) {
            $sync[(int) $locationId] = ['priority' => ($i + 1) * 10];
        }

        return $sync;
    }
}
