<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AppSetting;
use App\Models\PassengerExtraService;
use App\Models\PassengerExtraServiceItem;
use App\Models\PassengerExtraServiceRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class PassengerExtraServiceController extends Controller
{
    public function index(): JsonResponse
    {
        [$deliveryFee, $appFee] = $this->resolveFees();
        $items = PassengerExtraService::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->orderBy('id')
            ->get()
            ->map(fn ($s) => $this->formatService($s, $deliveryFee, $appFee));

        return response()->json([
            'success' => true,
            'data' => $items,
        ], 200, [], JSON_UNESCAPED_UNICODE);
    }

    public function show(int $id): JsonResponse
    {
        [$deliveryFee, $appFee] = $this->resolveFees();
        $s = PassengerExtraService::query()->where('is_active', true)->find($id);
        if (! $s) {
            return response()->json([
                'success' => false,
                'message' => 'الخدمة غير موجودة',
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => $this->formatService($s, $deliveryFee, $appFee, true),
        ], 200, [], JSON_UNESCAPED_UNICODE);
    }

    public function storeRequest(Request $request): JsonResponse
    {
        $request->validate([
            'passenger_extra_service_id' => 'required|integer|min:1',
            'notes' => 'nullable|string|max:2000',
            'contact_phone' => 'nullable|string|max:32',
            'items' => 'required|array|min:1',
            'items.*.id' => 'required|integer|min:1',
            'items.*.qty' => 'required|integer|min:1|max:99',
        ]);

        $service = PassengerExtraService::query()
            ->where('is_active', true)
            ->find((int) $request->input('passenger_extra_service_id'));

        if (! $service) {
            return response()->json([
                'success' => false,
                'message' => 'الخدمة غير متوفرة أو غير مفعّلة',
            ], 404);
        }

        $user = Auth::user();
        $itemsInput = collect($request->input('items', []))
            ->map(fn ($row) => [
                'id' => (int) ($row['id'] ?? 0),
                'qty' => max(1, (int) ($row['qty'] ?? 1)),
            ])
            ->filter(fn ($row) => $row['id'] > 0)
            ->values();

        $catalog = PassengerExtraServiceItem::query()
            ->where('passenger_extra_service_id', $service->id)
            ->where('is_active', true)
            ->whereIn('id', $itemsInput->pluck('id')->all())
            ->get()
            ->keyBy('id');

        if ($catalog->isEmpty()) {
            return response()->json([
                'success' => false,
                'message' => 'لا توجد عناصر صالحة في الطلب',
            ], 422);
        }

        $snapshot = [];
        $subtotal = 0.0;
        foreach ($itemsInput as $line) {
            /** @var PassengerExtraServiceItem|null $item */
            $item = $catalog->get($line['id']);
            if (! $item) {
                continue;
            }
            $qty = (int) $line['qty'];
            $unitPrice = (float) $item->price;
            $discountPercent = max(0.0, min(100.0, (float) $item->discount_percent));
            $unitFinal = round($unitPrice * (1 - ($discountPercent / 100)), 2);
            $lineTotal = round($unitFinal * $qty, 2);
            $subtotal += $lineTotal;

            $snapshot[] = [
                'item_id' => $item->id,
                'title' => $item->title,
                'unit_price' => $unitPrice,
                'discount_percent' => $discountPercent,
                'unit_final_price' => $unitFinal,
                'qty' => $qty,
                'line_total' => $lineTotal,
            ];
        }

        if (empty($snapshot)) {
            return response()->json([
                'success' => false,
                'message' => 'تعذر بناء سلة الطلب',
            ], 422);
        }

        [$deliveryFee, $appFee] = $this->resolveFees();
        $total = round($subtotal + $deliveryFee + $appFee, 2);

        $row = PassengerExtraServiceRequest::create([
            'user_id' => $user->id,
            'passenger_extra_service_id' => $service->id,
            'status' => 'pending',
            'notes' => $request->input('notes'),
            'contact_phone' => $request->input('contact_phone') ?: $user->phone,
            'items_snapshot' => $snapshot,
            'fee_snapshot' => round($subtotal, 2),
            'subtotal_amount' => round($subtotal, 2),
            'app_fee_amount' => $appFee,
            'delivery_fee_amount' => $deliveryFee,
            'total_amount' => $total,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'تم إرسال طلب الخدمة',
            'data' => $this->formatRequest($row->load('service')),
        ], 201, [], JSON_UNESCAPED_UNICODE);
    }

    public function myRequests(): JsonResponse
    {
        $user = Auth::user();
        $rows = PassengerExtraServiceRequest::query()
            ->where('user_id', $user->id)
            ->with('service')
            ->orderByDesc('created_at')
            ->get()
            ->map(fn ($r) => $this->formatRequest($r));

        return response()->json([
            'success' => true,
            'data' => $rows,
        ], 200, [], JSON_UNESCAPED_UNICODE);
    }

    private function formatService(
        PassengerExtraService $s,
        float $deliveryFee,
        float $appFee,
        bool $withItems = false
    ): array
    {
        $items = [];
        if ($withItems) {
            $items = $s->items()
                ->where('is_active', true)
                ->orderBy('sort_order')
                ->orderBy('id')
                ->get()
                ->map(fn (PassengerExtraServiceItem $item) => [
                    'id' => $item->id,
                    'title' => $item->title,
                    'subtitle' => $item->subtitle,
                    'image_url' => $item->imagePublicUrl(),
                    'price' => (float) $item->price,
                    'discount_percent' => (float) $item->discount_percent,
                    'final_price' => $item->finalPrice(),
                    'sort_order' => (int) $item->sort_order,
                ])
                ->values();
            $items = $items->all();
        }

        return [
            'id' => $s->id,
            'title' => $s->title,
            'subtitle' => $s->subtitle,
            'description' => $s->description,
            'image_url' => $s->imagePublicUrl(),
            'price_estimate' => $s->price_estimate !== null ? (float) $s->price_estimate : null,
            'sort_order' => (int) $s->sort_order,
            'delivery_fee' => $deliveryFee,
            'app_fee' => $appFee,
            'items' => $items,
        ];
    }

    private function formatRequest(PassengerExtraServiceRequest $r): array
    {
        return [
            'id' => $r->id,
            'passenger_extra_service_id' => $r->passenger_extra_service_id,
            'service_title' => $r->service?->title,
            'status' => $r->status,
            'notes' => $r->notes,
            'contact_phone' => $r->contact_phone,
            'items_snapshot' => $r->items_snapshot ?? [],
            'fee_snapshot' => (float) $r->fee_snapshot,
            'subtotal_amount' => (float) ($r->subtotal_amount ?? 0),
            'app_fee_amount' => (float) ($r->app_fee_amount ?? 0),
            'delivery_fee_amount' => (float) ($r->delivery_fee_amount ?? 0),
            'total_amount' => (float) ($r->total_amount ?? $r->fee_snapshot),
            'wheel_milestone_pending' => (bool) $r->wheel_milestone_pending,
            'wheel_result' => $r->wheel_result,
            'created_at' => $r->created_at?->toISOString(),
            'completed_at' => $r->completed_at?->toISOString(),
        ];
    }

    private function resolveFees(): array
    {
        $settings = AppSetting::query()->first();
        $deliveryFee = (float) ($settings?->passenger_extra_service_delivery_fee ?? 0);
        $appFee = (float) ($settings?->passenger_extra_service_app_fee ?? 600);

        return [
            max(0, round($deliveryFee, 2)),
            max(0, min(600, round($appFee, 2))),
        ];
    }
}
