<?php

namespace App\Http\Controllers\Api\V1;

use App\Domain\Financial\Enums\PaymentMethod;
use App\Domain\Financial\Enums\PaymentStatus;
use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Models\Payment;
use App\Domain\Financial\Services\PaymobService;
use App\Domain\Inventory\Models\Product;
use App\Domain\Participant\Models\Participant;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class OrderController extends Controller
{
    public function create(Request $request): JsonResponse
    {
        $request->validate([
            'participant_uuid' => 'required|string',
            'product_id' => 'required|integer|exists:products,id',
            'payment_method' => 'required|in:online,wallet',
            'installment_plan_id' => 'nullable|string',
        ]);

        $user = $request->user();
        $participant = $this->findAuthorized($request->participant_uuid, $user);

        $product = Product::where('id', $request->product_id)
            ->where('is_active', true)
            ->firstOrFail();

        // Duplicate check for essential products
        if ($product->is_essential) {
            $alreadyPurchased = Invoice::where('billable_type', 'App\\Domain\\Participant\\Models\\Participant')
                ->where('billable_id', $participant->id)
                ->whereNotIn('status', ['cancelled', 'draft'])
                ->whereHas('items', function ($q) use ($product) {
                    $q->where('itemable_type', 'App\\Domain\\Inventory\\Models\\Product')
                        ->where('itemable_id', $product->id);
                })
                ->where('created_at', '>=', now()->startOfYear())
                ->exists();

            if ($alreadyPurchased) {
                return response()->json([
                    'error' => 'already_purchased',
                    'message' => 'تم شراء هذا المنتج بالفعل هذا العام',
                ], 422);
            }
        }

        $price = $product->priceForTier(
            $participant->classification?->value ?? 'regular'
        );

        try {
            $result = DB::transaction(function () use ($participant, $product, $price, $user, $request) {
                $invoice = Invoice::create([
                    'academy_id' => $participant->academy_id,
                    'billable_type' => 'App\\Domain\\Participant\\Models\\Participant',
                    'billable_id' => $participant->id,
                    'number' => 'INV-MOB-' . now()->format('Ymd') . '-' . rand(1000, 9999),
                    'status' => 'sent',
                    'subtotal_amount' => $price,
                    'discount_amount' => 0,
                    'tax_amount' => 0,
                    'total_amount' => $price,
                    'paid_amount' => 0,
                    'due_amount' => $price,
                    'currency' => 'EGP',
                    'issue_date' => now()->toDateString(),
                    'due_date' => now()->addDays(7)->toDateString(),
                    'notes' => 'طلب من التطبيق — ' . $product->name_ar,
                    'created_by' => $user->id,
                ]);

                $invoice->items()->create([
                    'academy_id' => $participant->academy_id,
                    'itemable_type' => 'App\\Domain\\Inventory\\Models\\Product',
                    'itemable_id' => $product->id,
                    'description_ar' => $product->name_ar,
                    'description' => $product->name,
                    'quantity' => 1,
                    'unit_price' => $price,
                    'line_total' => $price,
                ]);

                return $invoice;
            });

            // If online payment, initiate Paymob
            if ($request->payment_method === 'online') {
                $paymobService = new PaymobService($user->academy_id);

                if (!$paymobService->isConfigured()) {
                    return response()->json([
                        'success' => true,
                        'message' => 'تم إنشاء الطلب — الدفع الإلكتروني غير مفعل، يرجى الدفع في الفرع',
                        'data' => [
                            'invoice_uuid' => $result->uuid,
                            'amount' => $price,
                            'amount_display' => number_format($price / 100, 2) . ' ج.م',
                            'payment_url' => null,
                        ],
                    ]);
                }

                try {
                    $paymentResult = $paymobService->createPaymentIntention($result, $user);

                    Payment::create([
                        'academy_id' => $result->academy_id,
                        'branch_id' => $result->branch_id,
                        'invoice_id' => $result->id,
                        'reference' => 'PMB-' . $paymentResult['order_id'],
                        'direction' => 'inbound',
                        'method' => PaymentMethod::Online,
                        'status' => PaymentStatus::Pending,
                        'payer_type' => 'App\\Domain\\Participant\\Models\\Participant',
                        'payer_id' => $participant->id,
                        'amount' => $price,
                        'currency' => 'EGP',
                        'payment_date' => now()->toDateString(),
                        'gateway_data' => [
                            'provider' => 'paymob',
                            'paymob_order_id' => $paymentResult['order_id'],
                        ],
                        'created_by' => $user->id,
                    ]);

                    return response()->json([
                        'success' => true,
                        'message' => 'تم إنشاء الطلب',
                        'data' => [
                            'invoice_uuid' => $result->uuid,
                            'amount' => $price,
                            'amount_display' => number_format($price / 100, 2) . ' ج.م',
                            'payment_url' => $paymentResult['iframe_url'],
                            'payment_key' => $paymentResult['payment_key'],
                        ],
                    ]);
                } catch (\Throwable $e) {
                    Log::error('[Order] Paymob initiation failed after invoice created', [
                        'invoice_uuid' => $result->uuid,
                        'error' => $e->getMessage(),
                    ]);

                    return response()->json([
                        'success' => true,
                        'message' => 'تم إنشاء الطلب لكن فشل بدء الدفع — يمكنك الدفع لاحقاً من الفواتير',
                        'data' => [
                            'invoice_uuid' => $result->uuid,
                            'amount' => $price,
                            'amount_display' => number_format($price / 100, 2) . ' ج.م',
                            'payment_url' => null,
                        ],
                    ]);
                }
            }

            // Wallet payment
            return response()->json([
                'success' => true,
                'message' => 'تم إنشاء الطلب — يرجى الدفع في الفرع أو عبر المحفظة',
                'data' => [
                    'invoice_uuid' => $result->uuid,
                    'amount' => $price,
                    'amount_display' => number_format($price / 100, 2) . ' ج.م',
                    'payment_url' => null,
                ],
            ]);
        } catch (\Throwable $e) {
            Log::error('[Order] Creation failed', ['error' => $e->getMessage()]);

            return response()->json([
                'error' => 'order_failed',
                'message' => 'فشل في إنشاء الطلب، يرجى المحاولة لاحقاً',
            ], 500);
        }
    }

    public function index(Request $request): JsonResponse
    {
        $user = $request->user();
        $participantUuid = $request->query('participant_uuid');

        if (!$participantUuid) {
            return response()->json(['error' => 'participant_uuid_required', 'message' => 'يرجى تحديد المشترك'], 422);
        }

        $participant = $this->findAuthorized($participantUuid, $user);

        $invoices = Invoice::where('billable_type', 'App\\Domain\\Participant\\Models\\Participant')
            ->where('billable_id', $participant->id)
            ->whereNotIn('status', ['cancelled', 'draft'])
            ->whereHas('items', function ($q) {
                $q->where('itemable_type', 'App\\Domain\\Inventory\\Models\\Product');
            })
            ->with('items')
            ->orderByDesc('created_at')
            ->paginate(15);

        return response()->json([
            'data' => $invoices->map(fn ($inv) => [
                'invoice_uuid' => $inv->uuid,
                'status' => $inv->status,
                'total_amount' => $inv->total_amount,
                'total_display' => number_format($inv->total_amount / 100, 2) . ' ج.م',
                'paid_amount' => $inv->paid_amount,
                'balance_due' => $inv->due_amount,
                'product_name' => $inv->items->first()?->description_ar,
                'created_at' => $inv->created_at?->toIso8601String(),
            ]),
            'meta' => [
                'current_page' => $invoices->currentPage(),
                'last_page' => $invoices->lastPage(),
                'per_page' => $invoices->perPage(),
                'total' => $invoices->total(),
            ],
        ]);
    }

    private function findAuthorized(string $uuid, $user): Participant
    {
        $participant = Participant::where('uuid', $uuid)->firstOrFail();
        $personId = $user->person_id;

        if (!$personId) {
            abort(403, 'غير مصرح لك بالوصول لهذا المشترك');
        }

        if ($participant->person_id === $personId) {
            return $participant;
        }

        $guardian = \App\Domain\Identity\Models\Guardian::where('person_id', $personId)->first();
        if ($guardian && $guardian->participants()->where('participants.id', $participant->id)->exists()) {
            return $participant;
        }

        abort(403, 'غير مصرح لك بالوصول لهذا المشترك');
    }
}
