<?php

namespace App\Http\Controllers\Admin\TopUp;

use App\Http\Controllers\Controller;
use App\Models\PakasirSettings;
use App\Models\PakasirTransaction;
use App\Services\Api\API;
use App\Traits\RefreshesSettingsCache;
use Illuminate\Http\Request;
use Inertia\Inertia;

class PakasirController extends Controller
{
    use RefreshesSettingsCache;

    protected API $api;

    public function __construct(API $api)
    {
        $this->api = $api;
    }

    private function getCallbackUrls(): array
    {
        $baseUrl = rtrim(config('app.url'), '/');

        return [
            'return_url' => $baseUrl.'/topup/pakasir/return',
            'notify_url' => $baseUrl.'/topup/pakasir/notify',
            'cancel_url' => $baseUrl.'/topup/pakasir/cancel',
        ];
    }

    public function index()
    {
        $settings = PakasirSettings::first();
        $transactions = PakasirTransaction::with('user')
            ->latest()
            ->paginate(50)
            ->withQueryString();

        $callbackUrls = $this->getCallbackUrls();

        return Inertia::render('admin/topup/pakasir/index', [
            'settings' => $settings ? [
                'slug' => $settings->slug,
                'api_key' => $settings->api_key,
                'production_mode' => $settings->production_mode,
                'gold_rate' => $settings->gold_rate,
                'min_amount' => $settings->min_amount,
                'max_amount' => $settings->max_amount,
                'is_active' => $settings->is_active,
                'broadcast_enabled' => $settings->broadcast_enabled ?? true,
                'broadcast_message' => $settings->broadcast_message,
                'broadcast_channel' => $settings->broadcast_channel ?? 9,
                'discord_enabled' => $settings->discord_enabled ?? false,
                'discord_webhook_url' => $settings->discord_webhook_url,
                'discord_message' => $settings->discord_message,
                'discord_mention_everyone' => $settings->discord_mention_everyone ?? false,
            ] : null,
            'transactions' => $transactions->items(),
            'paymentMethods' => $this->getPaymentMethods(),
            'callbackUrls' => $callbackUrls,
        ]);
    }

    public function updateSettings(Request $request)
    {
        $validated = $request->validate([
            'slug' => 'required|string',
            'api_key' => 'required|string',
            'production_mode' => 'required|boolean',
            'gold_rate' => 'required|integer|min:1',
            'min_amount' => 'required|integer|min:1000',
            'max_amount' => 'required|integer|min:10000',
            'is_active' => 'required|boolean',
            'broadcast_enabled' => 'nullable|boolean',
            'broadcast_message' => 'nullable|string|max:500',
            'broadcast_channel' => 'nullable|integer|min:1|max:99',
            'discord_enabled' => 'nullable|boolean',
            'discord_webhook_url' => 'nullable|url|max:500',
            'discord_message' => 'nullable|string|max:1000',
            'discord_mention_everyone' => 'nullable|boolean',
        ]);

        PakasirSettings::updateOrCreate(
            ['id' => PakasirSettings::first()?->id ?? 1],
            $validated
        );

        $this->refreshSettingsCache();

        return back()->with('success', 'Pakasir settings updated successfully.');
    }

    public function checkTransaction(Request $request)
    {
        $request->validate([
            'transaction_id' => 'required|string',
        ]);

        $settings = PakasirSettings::first();

        if (! $settings || ! $settings->isConfigured()) {
            return response()->json(['error' => 'Pakasir settings not configured'], 400);
        }

        try {
            $transaction = PakasirTransaction::where('reference_id', $request->transaction_id)
                ->orWhere('transaction_id', $request->transaction_id)
                ->first();

            if (! $transaction) {
                return response()->json(['error' => 'Transaction not found'], 404);
            }

            $detail = $settings->getTransactionDetail($transaction->reference_id, $transaction->amount);

            if ($detail && isset($detail['transaction'])) {
                $newStatus = PakasirTransaction::mapPakasirStatus($detail['transaction']['status']);
                $oldStatus = $transaction->status;

                $transaction->updateStatus($newStatus, $detail);

                // If status changed to success, process payment
                if ($newStatus === 'success' && $oldStatus !== 'success') {
                    $transaction->processPayment();
                }

                return response()->json($detail);
            }

            return response()->json(['error' => 'Failed to get transaction detail'], 500);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function syncTransaction(Request $request, $id)
    {
        $transaction = PakasirTransaction::find($id);

        if (! $transaction) {
            return back()->with('error', 'Transaction not found.');
        }

        $settings = PakasirSettings::first();

        if (! $settings || ! $settings->isConfigured()) {
            return back()->with('error', 'Pakasir settings not configured.');
        }

        try {
            $detail = $settings->getTransactionDetail($transaction->reference_id, $transaction->amount);

            if ($detail && isset($detail['transaction'])) {
                $newStatus = PakasirTransaction::mapPakasirStatus($detail['transaction']['status']);
                $oldStatus = $transaction->status;

                // Update transaction status
                $transaction->updateStatus($newStatus, $detail);

                // If status changed to success, process payment
                if ($newStatus === 'success' && $oldStatus !== 'success') {
                    $transaction->processPayment();

                    // Send broadcast notification if enabled
                    if ($settings && ($settings->broadcast_enabled ?? true)) {
                        try {
                            $user = $transaction->user;
                            if ($user) {
                                $message = $settings->getBroadcastMessage($user, $transaction);
                                $channel = $settings->broadcast_channel ?? 9;
                                $this->api->WorldChat(0, $message, $channel);
                            }
                        } catch (\Exception $e) {
                            \Log::error('Failed to send Pakasir donation broadcast on sync', [
                                'error' => $e->getMessage(),
                            ]);
                        }
                    }

                    // Send Discord notification if enabled
                    if ($settings && ($settings->discord_enabled ?? false)) {
                        try {
                            $user = $transaction->user;
                            if ($user) {
                                $settings->sendDiscordNotification($user, $transaction);
                            }
                        } catch (\Exception $e) {
                            \Log::error('Failed to send Pakasir Discord notification on sync', [
                                'error' => $e->getMessage(),
                            ]);
                        }
                    }

                    return back()->with('success', 'Transaction synced and gold added to user.');
                }

                return back()->with('success', 'Transaction synced successfully.');
            }

            return back()->with('error', 'Failed to sync transaction status.');
        } catch (\Exception $e) {
            return back()->with('error', 'Error syncing transaction: '.$e->getMessage());
        }
    }

    private function getPaymentMethods()
    {
        return [
            'qris' => [
                'name' => 'QRIS',
                'channels' => [
                    'qris' => 'QRIS (Quick Response Code Indonesian Standard)',
                ],
            ],
        ];
    }
}
