<?php

namespace App\Http\Controllers\Api\V1\Admin;

use App\Exceptions\DomainException;
use App\Http\Controllers\Controller;
use App\Http\Resources\LocationResource;
use App\Models\Location;
use App\Services\AuditService;
use App\Support\ApiResponse;
use Illuminate\Http\Request;

class LocationAdminController extends Controller
{
    use ApiResponse;

    public function __construct(private readonly AuditService $audit) {}

    public function index(Request $request)
    {
        return $this->success(LocationResource::collection(
            Location::query()
                ->where('organization_id', $request->user()->organization_id)
                ->orderBy('name')
                ->get()
        ));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:150'],
            'type' => ['required', 'string', 'max:60'],
            'address_line1' => ['nullable', 'string', 'max:190'],
            'address_line2' => ['nullable', 'string', 'max:190'],
            'city' => ['nullable', 'string', 'max:100'],
            'phone' => ['nullable', 'string', 'max:40'],
            'opening_hours_text' => ['nullable', 'string', 'max:2000'],
            'is_active' => ['sometimes', 'boolean'],
        ]);

        $location = Location::create($data + ['organization_id' => $request->user()->organization_id]);
        $this->audit->log('location.created', $request->user(), $location, null, $location->toArray());

        return $this->success(new LocationResource($location), 'Location created.', 201);
    }

    public function update(Request $request, Location $location)
    {
        if ($location->organization_id !== $request->user()->organization_id) {
            throw new DomainException('FORBIDDEN', 'Location belongs to another organization.', 403);
        }

        $data = $request->validate([
            'name' => ['sometimes', 'string', 'max:150'],
            'type' => ['sometimes', 'string', 'max:60'],
            'address_line1' => ['nullable', 'string', 'max:190'],
            'address_line2' => ['nullable', 'string', 'max:190'],
            'city' => ['nullable', 'string', 'max:100'],
            'phone' => ['nullable', 'string', 'max:40'],
            'opening_hours_text' => ['nullable', 'string', 'max:2000'],
            'is_active' => ['sometimes', 'boolean'],
        ]);

        $before = $location->toArray();
        $location->update($data);
        $this->audit->log('location.updated', $request->user(), $location, $before, $location->fresh()->toArray());

        return $this->success(new LocationResource($location->fresh()), 'Location updated.');
    }

    public function destroy(Request $request, Location $location)
    {
        if ($location->organization_id !== $request->user()->organization_id) {
            throw new DomainException('FORBIDDEN', 'Location belongs to another organization.', 403);
        }

        $location->update(['is_active' => false]);
        $this->audit->log('location.deactivated', $request->user(), $location);

        return $this->success(null, 'Location deactivated.');
    }
}
