<?php

namespace App\Http\Controllers\Admin\TopUp;

use App\Http\Controllers\Controller;
use App\Models\IpaymuSettings;
use App\Models\IpaymuTransaction;
use App\Services\Api\API;
use App\Traits\RefreshesSettingsCache;
use Illuminate\Http\Request;
use Inertia\Inertia;
use iPaymu\iPaymu;

class IpaymuController 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/ipaymu/return',
            'notify_url' => $baseUrl.'/topup/ipaymu/notify',
            'cancel_url' => $baseUrl.'/topup/ipaymu/cancel',
        ];
    }

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

        $callbackUrls = $this->getCallbackUrls();

        return Inertia::render('admin/topup/ipaymu/index', [
            'settings' => $settings ? [
                'api_key' => $settings->api_key,
                'va_number' => $settings->va_number,
                '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([
            'api_key' => 'required|string',
            'va_number' => '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',
        ]);

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

        $this->refreshSettingsCache();

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

    public function checkBalance()
    {
        $settings = IpaymuSettings::first();

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

        try {
            $iPaymu = new iPaymu($settings->api_key, $settings->va_number, $settings->production_mode);
            $balance = $iPaymu->checkBalance();

            return response()->json($balance);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

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

        $settings = IpaymuSettings::first();

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

        try {
            $iPaymu = new iPaymu($settings->api_key, $settings->va_number, $settings->production_mode);
            $status = $iPaymu->checkTransaction($request->transaction_id);

            // Update local transaction if exists
            $transaction = IpaymuTransaction::where('transaction_id', $request->transaction_id)->first();

            if ($transaction && isset($status['Data']['Status'])) {
                $newStatus = $this->mapIpaymuStatusString($status['Data']['Status']);
                $oldStatus = $transaction->status;

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

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

            return response()->json($status);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    private function mapIpaymuStatusString(string $status): string
    {
        $status = strtolower($status);

        return match ($status) {
            'berhasil', 'sukses', 'success', 'settled', 'paid' => 'success',
            'gagal', 'failed', 'fail', 'cancelled', 'canceled' => 'failed',
            'expired' => 'expired',
            default => 'pending',
        };
    }

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

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

        $settings = IpaymuSettings::first();

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

        try {
            $iPaymu = new iPaymu($settings->api_key, $settings->va_number, $settings->production_mode);
            $status = $iPaymu->checkTransaction($transaction->transaction_id);

            if (isset($status['Data']['Status'])) {
                $newStatus = $this->mapIpaymuStatusString($status['Data']['Status']);
                $oldStatus = $transaction->status;

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

                // 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 Ipaymu 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 Ipaymu 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 [
            'va' => [
                'name' => 'Virtual Account',
                'channels' => [
                    'bag' => 'Bank Artha Graha',
                    'bca' => 'Bank Central Asia',
                    'bni' => 'Bank Negara Indonesia',
                    'cimb' => 'Bank CIMB Niaga',
                    'mandiri' => 'Bank Mandiri',
                    'bmi' => 'Bank Muamalat Indonesia',
                    'bri' => 'Bank Rakyat Indonesia',
                    'bsi' => 'Bank Syariah Indonesia',
                    'permata' => 'Bank Permata',
                    'danamon' => 'Bank Danamon',
                ],
            ],
            'cstore' => [
                'name' => 'Convenience Store',
                'channels' => [
                    'indomaret' => 'Indomaret',
                    'alfamart' => 'Alfamart',
                ],
            ],
            'qris' => [
                'name' => 'QRIS',
                'channels' => [
                    'qris' => 'QRIS',
                ],
            ],
        ];
    }
}
