<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Services\SerenataIntegrationService;
use App\Support\Authorization\PermissionCatalog;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class SerenataIntegrationController extends Controller
{
    public function __construct(private readonly SerenataIntegrationService $service) {}

    public function index(Request $request)
    {
        $user = $request->user();
        abort_unless($user->can(PermissionCatalog::permissionName(PermissionCatalog::PANEL_OWNER, 'serenatas', 'view')), 403);

        $data = $request->validate([
            'phone' => ['nullable', 'string', 'max:40'],
            'email' => ['nullable', 'string', 'email', 'max:255'],
            'external_reference' => ['nullable', 'string', 'max:120'],
            'code' => ['nullable', 'string', 'max:120'],
            'event_date' => ['nullable', 'date_format:Y-m-d'],
            'limit' => ['nullable', 'integer', 'min:1', 'max:50'],
        ]);

        $filters = array_filter([
            'phone' => trim((string) ($data['phone'] ?? '')),
            'email' => trim((string) ($data['email'] ?? '')),
            'external_reference' => trim((string) ($data['external_reference'] ?? '')),
            'code' => trim((string) ($data['code'] ?? '')),
            'event_date' => trim((string) ($data['event_date'] ?? '')),
        ], fn ($value) => $value !== '');

        if ($filters === []) {
            throw ValidationException::withMessages([
                'filters' => 'Envía al menos uno de estos filtros: `phone`, `email`, `external_reference`, `code`, `event_date`.',
            ]);
        }

        $limit = isset($data['limit']) ? (int) $data['limit'] : 10;
        $result = $this->service->searchAccessibleSerenatas($user, $filters, $limit);

        return response()->json($result);
    }

    public function me(Request $request)
    {
        $user = $request->user();

        return response()->json([
            'user' => [
                'id' => (int) $user->id,
                'name' => (string) $user->name,
                'email' => (string) $user->email,
                'role' => (string) $user->role,
                'organization_id' => (int) $user->organization_id,
            ],
        ]);
    }

    public function catalog(Request $request)
    {
        $user = $request->user();
        abort_unless($user->can(PermissionCatalog::permissionName(PermissionCatalog::PANEL_OWNER, 'serenatas', 'view')), 403);

        $data = $request->validate([
            'event_date' => ['nullable', 'date_format:Y-m-d'],
            'mariachi_group_id' => ['nullable', 'integer', 'min:1'],
        ]);

        return response()->json([
            'catalog' => $this->service->catalogForUser(
                $user,
                $data['event_date'] ?? null,
                isset($data['mariachi_group_id']) ? (int) $data['mariachi_group_id'] : null
            ),
        ]);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        abort_unless($user->can(PermissionCatalog::permissionName(PermissionCatalog::PANEL_OWNER, 'serenatas', 'create')), 403);

        $data = $request->validate([
            'submission_token' => ['nullable', 'string', 'max:120'],
            'external_reference' => ['nullable', 'string', 'max:120'],
            'mariachi_group_id' => ['required', 'integer', 'min:1'],
            'serenata_package_id' => ['nullable', 'integer', 'min:1'],
            'payer_name' => ['required', 'string', 'max:255'],
            'payer_email' => ['nullable', 'string', 'lowercase', 'email', 'max:255'],
            'service_address' => ['required', 'string', 'max:255'],
            'address_additional' => ['nullable', 'string', 'max:255'],
            'service_country' => ['nullable', 'string', 'max:80'],
            'service_department' => ['nullable', 'string', 'max:120'],
            'neighborhood' => ['required', 'string', 'max:120'],
            'locality' => ['required', 'string', 'max:120'],
            'service_locality' => ['nullable', 'string', 'max:120'],
            'service_sector' => ['nullable', 'string', 'max:120'],
            'contact_phone_1' => ['required', 'string', 'max:40'],
            'contact_phone_2' => ['nullable', 'string', 'max:40'],
            'reason' => ['required', 'string', 'max:255'],
            'from_name' => ['required', 'string', 'max:255'],
            'to_name' => ['required', 'string', 'max:255'],
            'event_date' => ['required', 'date_format:Y-m-d'],
            'event_time' => ['required', 'date_format:H:i'],
            'internal_notes' => ['nullable', 'string', 'max:1200'],
            'client_notes' => ['nullable', 'string', 'max:1200'],
            'base_price' => ['nullable', 'numeric', 'min:0'],
            'gift_amount' => ['nullable', 'numeric', 'min:0'],
            'artist_amount' => ['nullable', 'numeric', 'min:0'],
            'other_cost_amount' => ['nullable', 'numeric', 'min:0'],
            'discount_amount' => ['nullable', 'numeric', 'min:0'],
            'commission_rate' => ['nullable', 'numeric', 'min:0', 'max:100'],
            'payment_method' => ['nullable', 'string', 'max:120'],
            'service_status' => ['nullable', 'string', 'max:40'],
            'cancellation_reason' => ['nullable', 'string', 'max:600'],
            'gift_items' => ['nullable', 'array'],
            'gift_items.*.code' => ['required', 'string', 'max:120'],
            'gift_items.*.quantity' => ['nullable', 'integer', 'min:1'],
            'gift_items.*.unit_price' => ['nullable', 'numeric', 'min:0'],
            'artist_items' => ['nullable', 'array'],
            'artist_items.*.code' => ['required', 'string', 'max:120'],
            'artist_items.*.quantity' => ['nullable', 'integer', 'min:1'],
            'artist_items.*.unit_price' => ['nullable', 'numeric', 'min:0'],
            'other_cost_items' => ['nullable', 'array'],
            'other_cost_items.*.code' => ['required', 'string', 'max:120'],
            'other_cost_items.*.quantity' => ['nullable', 'integer', 'min:1'],
            'other_cost_items.*.unit_price' => ['nullable', 'numeric', 'min:0'],
        ]);

        $result = $this->service->createForUser($user, $data, $request->header('Idempotency-Key'));

        return response()->json([
            'created' => (bool) $result['created'],
            'serenata' => $this->service->serializeSerenata($result['serenata']),
        ], $result['created'] ? 201 : 200);
    }

    public function show(Request $request, string $reference)
    {
        $user = $request->user();
        abort_unless($user->can(PermissionCatalog::permissionName(PermissionCatalog::PANEL_OWNER, 'serenatas', 'view')), 403);

        $serenata = $this->service->findAccessibleSerenata($user, $reference);
        abort_unless($serenata, 404);

        return response()->json([
            'serenata' => $this->service->serializeSerenata($serenata),
        ]);
    }
}
