﻿<?php

use App\Models\Contribution;
use App\Models\Transaction;
use App\Services\MpesaService;
use Illuminate\Support\Facades\DB;
use Livewire\Component;

new class extends Component
{
    public Contribution $contribution;

    public string $payment_method = 'manual';

    public string $payment_reference = '';

    public string $notes = '';

    public function mount(Contribution $contribution): void
    {
        $this->contribution = $contribution->load([
            'chama',
            'fund',
            'contributionPlan',
            'user',
        ]);

        abort_unless(
            $this->canPayContribution(),
            403
        );
    }

    private function canPayContribution(): bool
    {
        if ($this->contribution->user_id === auth()->id()) {
            return true;
        }

        return $this->contribution->chama->members()
            ->where('user_id', auth()->id())
            ->where('status', 'active')
            ->whereIn('role', ['chairperson', 'admin', 'treasurer'])
            ->exists();
    }

    public function isPaid(): bool
    {
        return $this->contribution->status === 'paid';
    }

    public function pay(): void
    {
        abort_unless(
            $this->canPayContribution(),
            403
        );

        $this->validate([
            'payment_method' => ['required', 'in:manual,mpesa,bank'],
            'payment_reference' => ['nullable', 'string', 'max:255'],
            'notes' => ['nullable', 'string', 'max:1000'],
        ]);

        if ($this->payment_method === 'mpesa') {
            $this->startMpesaPayment();

            return;
        }

        $reference = trim($this->payment_reference);

        if ($reference === '') {
            $reference = 'MANUAL-' . now()->format('YmdHis') . '-' . $this->contribution->id;
        }

        DB::transaction(function () use ($reference) {
            $contribution = Contribution::query()
                ->whereKey($this->contribution->id)
                ->lockForUpdate()
                ->firstOrFail();

            if ($contribution->status === 'paid') {
                throw new \RuntimeException(
                    'This contribution has already been marked as paid.'
                );
            }

            $contribution->load([
                'chama',
                'fund',
                'contributionPlan',
            ]);

            if (! $contribution->fund) {
                throw new \RuntimeException(
                    'This contribution is not assigned to a chama fund.'
                );
            }

            $contribution->update([
                'status' => 'paid',
                'paid_at' => now(),
                'payment_reference' => $reference,
                'payment_method' => $this->payment_method,
                'notes' => $this->notes ?: null,
            ]);

            Transaction::create([
                'chama_id' => $contribution->chama_id,
                'chama_fund_id' => $contribution->chama_fund_id,
                'user_id' => $contribution->user_id,
                'contribution_id' => $contribution->id,
                'type' => 'contribution',
                'amount' => $contribution->amount,
                'currency' => $contribution->fund->currency,
                'status' => 'completed',
                'payment_method' => $this->payment_method,
                'reference' => $reference,
                'external_reference' => null,
                'description' => 'Contribution payment',
                'processed_at' => now(),
            ]);
        });

        $this->contribution->refresh();

        session()->flash(
            'success',
            'Contribution paid successfully.'
        );

        $this->redirect(
            route('chamas.show', $this->contribution->chama->slug),
            navigate: true
        );
    }

    private function startMpesaPayment(): void
    {
        $payment = DB::transaction(function (): array {
            $contribution = Contribution::query()
                ->whereKey($this->contribution->id)
                ->lockForUpdate()
                ->firstOrFail();

            if ($contribution->status === 'paid') {
                throw new \RuntimeException(
                    'This contribution has already been marked as paid.'
                );
            }

            $contribution->load([
                'chama',
                'fund',
                'user',
            ]);

            if (! $contribution->fund) {
                throw new \RuntimeException(
                    'This contribution is not assigned to a chama fund.'
                );
            }

            $phoneNumber = trim((string) $contribution->user?->phone_number);

            if (config('mpesa.environment') === 'sandbox') {
                $phoneNumber = trim(
                    (string) config('mpesa.sandbox_phone_number', $phoneNumber)
                );
            }

            if ($phoneNumber === '') {
                throw new \RuntimeException(
                    'The contribution member does not have a phone number saved for M-PESA.'
                );
            }

            $existingPayment = Transaction::query()
                ->where('contribution_id', $contribution->id)
                ->where('payment_method', 'mpesa')
                ->where('status', 'pending')
                ->exists();

            if ($existingPayment) {
                $this->addError(
                    'payment_method',
                    'An M-PESA payment request is already pending for this contribution. Please complete it before trying again.'
                );

                return [
                    'transaction_id' => null,
                    'phone_number' => $phoneNumber,
                    'amount' => $contribution->amount,
                    'account_reference' => 'CH' . $contribution->id,
                ];
            }

            $reference = 'MPESA-' . $contribution->id . '-' . now()->format('YmdHis');

            $transaction = Transaction::create([
                'chama_id' => $contribution->chama_id,
                'chama_fund_id' => $contribution->chama_fund_id,
                'user_id' => $contribution->user_id,
                'contribution_id' => $contribution->id,
                'type' => 'contribution',
                'amount' => $contribution->amount,
                'currency' => $contribution->fund->currency,
                'status' => 'pending',
                'payment_method' => 'mpesa',
                'reference' => $reference,
                'external_reference' => null,
                'gateway_reference' => null,
                'description' => 'M-PESA STK payment',
                'processed_at' => null,
            ]);

            return [
                'transaction_id' => $transaction->id,
                'phone_number' => $phoneNumber,
                'amount' => $contribution->amount,
                'account_reference' => 'CH' . $contribution->id,
            ];
        });

        try {
            $response = app(MpesaService::class)->stkPush(
                $payment['phone_number'],
                $payment['amount'],
                $payment['account_reference'],
                'Chama payment'
            );

            Transaction::query()
                ->whereKey($payment['transaction_id'])
                ->update([
                    'gateway_reference' => $response['CheckoutRequestID'],
                ]);
        } catch (\Throwable $exception) {
            Transaction::query()
                ->whereKey($payment['transaction_id'])
                ->update([
                    'status' => 'failed',
                    'description' => 'M-PESA STK request failed: ' . $exception->getMessage(),
                    'processed_at' => now(),
                ]);

            $this->addError(
                'payment_method',
                $exception->getMessage()
            );

            return;
        }

        session()->flash(
            'success',
            'M-PESA payment request sent. Check the configured sandbox/test phone and complete the prompt.'
        );

        $this->redirect(
            route('chamas.show', $this->contribution->chama->slug),
            navigate: true
        );
    }
};
?>

<div class="mx-auto max-w-3xl space-y-6">
    <div>
        <a
            href="{{ route('chamas.show', $contribution->chama->slug) }}"
            wire:navigate
            class="inline-flex items-center gap-2 text-sm font-medium text-indigo-600 transition hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300"
        >
            <span aria-hidden="true">&larr;</span>
            Back to {{ $contribution->chama->name }}
        </a>

        <div class="mt-4">
            <div class="flex flex-wrap items-center gap-2">
                <p class="text-sm font-medium text-zinc-500 dark:text-zinc-400">
                    {{ $contribution->chama->name }}
                </p>

                @if ($this->isPaid())
                    <flux:badge color="green">
                        Paid
                    </flux:badge>
                @elseif ($contribution->due_date && $contribution->due_date->isBefore(today()))
                    <flux:badge color="red">
                        Overdue
                    </flux:badge>
                @else
                    <flux:badge color="yellow">
                        Pending
                    </flux:badge>
                @endif
            </div>

            <h1 class="mt-1 text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
                {{ $this->isPaid() ? 'Contribution Payment Record' : 'Pay Contribution' }}
            </h1>

            <p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
                {{ $contribution->contributionPlan?->name ?? 'Contribution' }}
            </p>
        </div>
    </div>

    @if ($this->isPaid())
        <div class="rounded-2xl border border-emerald-200 bg-emerald-50 p-5 dark:border-emerald-900/50 dark:bg-emerald-950/30">
            <div class="flex items-start gap-3">
                <div class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-lg font-bold text-emerald-700 dark:bg-emerald-900/60 dark:text-emerald-300">
                    
                </div>

                <div>
                    <h2 class="font-semibold text-emerald-900 dark:text-emerald-200">
                        Contribution already paid
                    </h2>

                    <p class="mt-1 text-sm leading-6 text-emerald-800 dark:text-emerald-300">
                        This contribution has already been recorded as paid. No additional payment is required.
                    </p>
                </div>
            </div>
        </div>
    @endif

    @if ($errors->has('payment_method'))
        <div class="rounded-2xl border border-red-200 bg-red-50 p-4 dark:border-red-900/50 dark:bg-red-950/30">
            <p class="text-sm font-medium text-red-800 dark:text-red-300">
                {{ $errors->first('payment_method') }}
            </p>
        </div>
    @endif

    <div class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
        <div class="border-b border-zinc-200 px-6 py-5 dark:border-zinc-700">
            <p class="text-sm font-medium text-zinc-500 dark:text-zinc-400">
                Contribution amount
            </p>

            <div class="mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1">
                <span class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
                    {{ $contribution->fund?->currency ?? $contribution->chama->currency }}
                    {{ number_format($contribution->amount, 2) }}
                </span>

                <span class="text-sm text-zinc-500 dark:text-zinc-400">
                    {{ $contribution->contributionPlan?->frequency ?? 'scheduled' }}
                </span>
            </div>
        </div>

        <div class="grid gap-px bg-zinc-200 sm:grid-cols-2 dark:bg-zinc-700">
            <div class="bg-white p-5 dark:bg-zinc-900">
                <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                    Due Date
                </p>

                <p class="mt-1 font-semibold text-zinc-900 dark:text-white">
                    {{ $contribution->due_date->format('d M Y') }}
                </p>
            </div>

            <div class="bg-white p-5 dark:bg-zinc-900">
                <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                    Fund
                </p>

                <p class="mt-1 font-semibold text-zinc-900 dark:text-white">
                    {{ $contribution->fund?->name ?? 'Not assigned' }}
                </p>
            </div>

            @if ($this->isPaid())
                <div class="bg-white p-5 dark:bg-zinc-900">
                    <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                        Paid At
                    </p>

                    <p class="mt-1 font-semibold text-zinc-900 dark:text-white">
                        {{ $contribution->paid_at?->format('d M Y, H:i') ?? '' }}
                    </p>
                </div>

                <div class="bg-white p-5 dark:bg-zinc-900">
                    <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                        Payment Method
                    </p>

                    <p class="mt-1 font-semibold capitalize text-zinc-900 dark:text-white">
                        {{ $contribution->payment_method ?? '' }}
                    </p>
                </div>

                <div class="bg-white p-5 sm:col-span-2 dark:bg-zinc-900">
                    <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                        Payment Reference
                    </p>

                    <p class="mt-1 break-all font-mono text-sm font-semibold text-zinc-900 dark:text-white">
                        {{ $contribution->payment_reference ?? '' }}
                    </p>
                </div>

                @if ($contribution->notes)
                    <div class="bg-white p-5 sm:col-span-2 dark:bg-zinc-900">
                        <p class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
                            Payment Notes
                        </p>

                        <p class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300">
                            {{ $contribution->notes }}
                        </p>
                    </div>
                @endif
            @endif
        </div>
    </div>

    @if (! $this->isPaid())
        <form wire:submit="pay" class="space-y-5">
            <div class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
                <div>
                    <h2 class="text-lg font-semibold text-zinc-900 dark:text-white">
                        Payment Details
                    </h2>

                    <p class="mt-1 text-sm leading-6 text-zinc-500 dark:text-zinc-400">
                        Record how this contribution was paid. The payment will be added to the selected fund and transaction ledger.
                    </p>
                </div>

                <div class="mt-6 space-y-5">
                    <div>
                        <label
                            for="payment_method"
                            class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-300"
                        >
                            Payment Method
                        </label>

                        <select
                            id="payment_method"
                            wire:model="payment_method"
                            class="w-full rounded-xl border-zinc-300 bg-white px-3 py-2.5 text-sm text-zinc-900 focus:border-indigo-500 focus:ring-indigo-500 dark:border-zinc-600 dark:bg-zinc-800 dark:text-white"
                        >
                            <option value="manual">Manual / Cash</option>
                            <option value="mpesa">M-PESA</option>
                            <option value="bank">Bank Transfer</option>
                        </select>

                        @error('payment_method')
                            <p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
                        @enderror
                    </div>

                    <div>
                        <label
                            for="payment_reference"
                            class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-300"
                        >
                            Payment Reference
                        </label>

                        <input
                            id="payment_reference"
                            type="text"
                            wire:model="payment_reference"
                            placeholder="e.g. M-PESA transaction code"
                            class="w-full rounded-xl border-zinc-300 bg-white px-3 py-2.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-indigo-500 focus:ring-indigo-500 dark:border-zinc-600 dark:bg-zinc-800 dark:text-white dark:placeholder:text-zinc-500"
                        >

                        <p class="mt-2 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
                            Leave blank to generate a reference automatically.
                        </p>

                        @error('payment_reference')
                            <p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
                        @enderror
                    </div>

                    <div>
                        <label
                            for="notes"
                            class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-300"
                        >
                            Notes
                        </label>

                        <textarea
                            id="notes"
                            wire:model="notes"
                            rows="4"
                            placeholder="Optional payment notes"
                            class="w-full rounded-xl border-zinc-300 bg-white px-3 py-2.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-indigo-500 focus:ring-indigo-500 dark:border-zinc-600 dark:bg-zinc-800 dark:text-white dark:placeholder:text-zinc-500"
                        ></textarea>

                        @error('notes')
                            <p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
                        @enderror
                    </div>
                </div>
            </div>

            <div class="flex flex-col-reverse gap-3 sm:flex-row sm:justify-end">
                <a
                    href="{{ route('chamas.show', $contribution->chama->slug) }}"
                    class="inline-flex items-center justify-center rounded-xl border border-zinc-300 px-5 py-3 text-sm font-semibold text-zinc-700 transition hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800"
                >
                    Cancel
                </a>

                <button
                    type="submit"
                    wire:loading.attr="disabled"
                    class="inline-flex items-center justify-center rounded-xl bg-indigo-600 px-5 py-3 text-sm font-semibold text-white shadow-sm transition hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-50"
                >
                    <span wire:loading.remove>
                        Pay Contribution
                    </span>

                    <span wire:loading>
                        Processing...
                    </span>
                </button>
            </div>
        </form>
    @else
        <div class="flex flex-col gap-3 sm:flex-row sm:justify-end">
            <a
                href="{{ route('contributions.history', $contribution->chama->slug) }}"
                wire:navigate
                class="inline-flex items-center justify-center rounded-xl border border-zinc-300 px-5 py-3 text-sm font-semibold text-zinc-700 transition hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800"
            >
                View Contribution History
            </a>

            <a
                href="{{ route('chamas.show', $contribution->chama->slug) }}"
                wire:navigate
                class="inline-flex items-center justify-center rounded-xl bg-indigo-600 px-5 py-3 text-sm font-semibold text-white transition hover:bg-indigo-700"
            >
                Back to Chama
            </a>
        </div>
    @endif
</div>


