<?php

namespace App\Http\Controllers\Api;

use App\Core\Http\Controllers\BaseApiController;
use App\Models\PaymentMethod;
use App\Models\PaymentSubmission;
use App\Models\SubscriptionPlan;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * وسائل الدفع وإرسال طلبات الدفع للمراجعة.
 */
class PaymentController extends BaseApiController
{
    public function methods(): JsonResponse
    {
        $rows = PaymentMethod::query()
            ->where('is_enabled', true)
            ->orderBy('sort_order')
            ->orderBy('id')
            ->get()
            ->map(static fn (PaymentMethod $m) => [
                'id' => $m->id,
                'slug' => $m->slug,
                'name_ar' => $m->name_ar,
                'account_label' => $m->account_label,
                'account_value' => $m->account_value,
                'instructions' => $m->instructions,
            ])
            ->values()
            ->all();

        return $this->successResponse('OK', ['items' => $rows]);
    }

    public function index(Request $request): JsonResponse
    {
        $user = $request->user();
        $rows = PaymentSubmission::query()
            ->where('user_id', $user->id)
            ->with(['paymentMethod:id,slug,name_ar', 'subscriptionPlan:id,name,slug'])
            ->orderByDesc('id')
            ->limit(50)
            ->get()
            ->map(static fn (PaymentSubmission $s) => self::submissionPayload($s))
            ->all();

        return $this->successResponse('OK', ['items' => $rows]);
    }

    public function store(Request $request): JsonResponse
    {
        $user = $request->user();

        $data = $request->validate([
            'payment_method_id' => ['required', 'integer', 'exists:payment_methods,id'],
            'purpose' => ['required', 'string', 'in:wallet_topup,subscription'],
            'amount' => ['required', 'numeric', 'min:0.01', 'max:99999999'],
            'subscription_plan_id' => ['nullable', 'integer', 'exists:subscription_plans,id'],
            'payer_reference' => ['required', 'string', 'max:120'],
            'payer_note' => ['nullable', 'string', 'max:2000'],
            'proof' => ['nullable', 'file', 'max:5120', 'mimes:jpg,jpeg,png,pdf'],
        ]);

        $method = PaymentMethod::query()->whereKey($data['payment_method_id'])->firstOrFail();
        if (! $method->is_enabled) {
            return $this->errorResponse('وسيلة الدفع غير مفعّلة حالياً.', ['code' => 'payment_method_disabled'], 422);
        }

        $amount = round((float) $data['amount'], 2);

        if ($data['purpose'] === PaymentSubmission::PURPOSE_SUBSCRIPTION) {
            if (empty($data['subscription_plan_id'])) {
                return $this->errorResponse('يجب اختيار خطة الاشتراك.', ['code' => 'plan_required'], 422);
            }
            $plan = SubscriptionPlan::query()->whereKey($data['subscription_plan_id'])->where('status', 'active')->first();
            if ($plan === null) {
                return $this->errorResponse('الخطة غير متاحة.', ['code' => 'plan_invalid'], 422);
            }
            $expected = round((float) $plan->price, 2);
            if ($expected > 0 && abs($amount - $expected) > 0.01) {
                return $this->errorResponse(
                    'المبلغ يجب أن يطابق سعر الخطة ('.$expected.').',
                    ['code' => 'amount_mismatch'],
                    422
                );
            }
        }

        $proofPath = null;
        if ($request->hasFile('proof')) {
            $proofPath = $request->file('proof')->store('payments/proofs/'.$user->id, 'local');
        }

        $submission = PaymentSubmission::query()->create([
            'user_id' => $user->id,
            'payment_method_id' => $method->id,
            'purpose' => $data['purpose'],
            'amount' => $amount,
            'subscription_plan_id' => $data['subscription_plan_id'] ?? null,
            'payer_reference' => $data['payer_reference'],
            'payer_note' => $data['payer_note'] ?? null,
            'proof_path' => $proofPath,
            'status' => PaymentSubmission::STATUS_PENDING,
        ]);

        $submission->load(['paymentMethod:id,slug,name_ar', 'subscriptionPlan:id,name,slug']);

        return $this->successResponse(
            'تم إرسال طلب الدفع. سيراجعه المدير قريباً.',
            ['submission' => self::submissionPayload($submission)],
            201
        );
    }

    /**
     * @return array<string, mixed>
     */
    private static function submissionPayload(PaymentSubmission $s): array
    {
        return [
            'id' => $s->id,
            'purpose' => $s->purpose,
            'amount' => (string) $s->amount,
            'status' => $s->status,
            'payer_reference' => $s->payer_reference,
            'payer_note' => $s->payer_note,
            'admin_note' => $s->admin_note,
            'payment_method' => $s->relationLoaded('paymentMethod') && $s->paymentMethod
                ? [
                    'id' => $s->paymentMethod->id,
                    'slug' => $s->paymentMethod->slug,
                    'name_ar' => $s->paymentMethod->name_ar,
                ]
                : null,
            'subscription_plan' => $s->relationLoaded('subscriptionPlan') && $s->subscriptionPlan
                ? [
                    'id' => $s->subscriptionPlan->id,
                    'name' => $s->subscriptionPlan->name,
                    'slug' => $s->subscriptionPlan->slug,
                ]
                : null,
            'created_at' => $s->created_at?->toIso8601String(),
            'reviewed_at' => $s->reviewed_at?->toIso8601String(),
        ];
    }
}
