<?php

namespace App\Http\Controllers;

use App\Http\Requests\StorePaymentRequest;
use App\Models\Account;
use App\Models\Activity;
use App\Models\Booking;
use App\Models\Payment;
use App\Models\PaymentSetting;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response;

class AccountPaymentController extends Controller
{
    public function index(Account $account): Response
    {
        $payments = Payment::query()
            ->where('account_id', $account->id)
            ->orderByDesc('paid_at')
            ->get(['id', 'amount', 'balance_before', 'currency', 'reference', 'paid_at', 'created_at'])
            ->map(function (Payment $p) {
                return [
                    'id' => $p->id,
                    'amount' => (float) $p->amount,
                    'balance_before' => (float) ($p->balance_before ?? 0),
                    'currency' => $p->currency,
                    'reference' => $p->reference,
                    'paid_at' => $p->paid_at,
                    'created_at' => $p->created_at,
                ];
            });

        return Inertia::render('Accounts/Payments/Index', [
            'account' => $account->only(['id', 'reference', 'description']),
            'payments' => $payments,
        ]);
    }

    public function list(Account $account): JsonResponse
    {
        $payments = Payment::query()
            ->where('account_id', $account->id)
            ->orderByDesc('paid_at')
            ->get(['id', 'amount', 'balance_before', 'currency', 'reference', 'paid_at', 'created_at'])
            ->map(function (Payment $p) {
                return [
                    'id' => $p->id,
                    'amount' => (float) $p->amount,
                    'balance_before' => (float) ($p->balance_before ?? 0),
                    'currency' => $p->currency,
                    'reference' => $p->reference,
                    'paid_at' => optional($p->paid_at)?->toDateString(),
                    'created_at' => optional($p->created_at)?->toDateTimeString(),
                ];
            });

        return response()->json([
            'account' => [
                'id' => $account->id,
                'balance_amount' => $account->balance_amount,
            ],
            'payments' => $payments,
        ]);
    }

    public function store(StorePaymentRequest $request, Account $account): RedirectResponse
    {
        $validated = $request->validated();

        $amountCents = (int) round(((float) $validated['amount']) * 100);

        // Load defaults from settings
        $settings = PaymentSetting::query()->first();
        $defaultCurrency = strtoupper($settings->default_currency ?? 'EUR');

        $payment = Payment::query()->create([
            'account_id' => $account->id,
            'balance_before' => (float) ($account->balance_amount ?? 0),
            'amount' => (float) $validated['amount'],
            'currency' => strtoupper($validated['currency'] ?? $defaultCurrency),
            'reference' => $validated['reference'] ?? null,
            'paid_at' => $validated['paid_at'] ?? now(),
            'meta' => $validated['meta'] ?? null,
            'created_by' => $request->user()?->id,
        ]);

        // Auto-create a credit booking for this payment to reduce account balance
        Booking::query()->create([
            'account_id' => $account->id,
            'payment_id' => $payment->id,
            'amount_cents' => $amountCents,
            'type' => 'credit',
            'description' => $payment->reference ? ('Plačilo '.$payment->reference) : 'Plačilo',
            'booked_at' => $payment->paid_at ?? now(),
        ]);

        // Optionally create an activity entry with default decision/action
        if ($settings && ($settings->create_activity_on_payment ?? false)) {
            $note = $settings->activity_note_template ?? 'Prejeto plačilo';
            $note = str_replace(['{amount}', '{currency}'], [number_format($amountCents / 100, 2, ',', '.'), $payment->currency], $note);

            // Append balance context and cause
            $account->refresh();
            $beforeStr = number_format((float) ($payment->balance_before ?? 0), 2, ',', '.').' '.$payment->currency;
            $afterStr = number_format((float) ($account->balance_amount ?? 0), 2, ',', '.').' '.$payment->currency;
            $note .= " (Stanje pred: {$beforeStr}, Stanje po: {$afterStr}; Izvor: plačilo)";

            $account->loadMissing('contract');
            $clientCaseId = $account->contract?->client_case_id;
            if ($clientCaseId) {
                $activity = Activity::query()->create([
                    'due_date' => null,
                    'amount' => $amountCents / 100,
                    'note' => $note,
                    'action_id' => $settings->default_action_id,
                    'decision_id' => $settings->default_decision_id,
                    'client_case_id' => $clientCaseId,
                    'contract_id' => $account->contract_id,
                ]);
                // Link the payment to the activity
                $payment->update(['activity_id' => $activity->id]);
            }
        }

        return back()->with('success', 'Payment created.');
    }

    public function destroy(Account $account, Payment $payment): RedirectResponse|JsonResponse
    {
        if ($payment->account_id !== $account->id) {
            abort(404);
        }

        // Delete related booking(s) to revert balance via model events
        Booking::query()->where('payment_id', $payment->id)->get()->each->delete();

        // Optionally delete related activity
        if ($payment->activity_id ?? null) {
            $activity = Activity::query()->find($payment->activity_id);
            if ($activity) {
                $activity->delete();
            }
        }

        $payment->delete();

        if (request()->wantsJson()) {
            $account->refresh();

            return response()->json([
                'ok' => true,
                'balance_amount' => $account->balance_amount,
            ]);
        }

        return back()->with('success', 'Payment deleted.');
    }
}
