<?php

namespace App\Http\Controllers\Admin\TopUp;

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

class DuitkuController 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/duitku/return',
            'callback_url' => $baseUrl.'/topup/duitku/callback',
        ];
    }

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

        $callbackUrls = $this->getCallbackUrls();

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

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

        $this->refreshSettingsCache();

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

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

        $settings = DuitkuSettings::first();

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

        try {
            $transaction = DuitkuTransaction::where('merchant_order_id', $request->merchant_order_id)->first();

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

            // Call Duitku API to check transaction status
            $apiUrl = $settings->status_check_url;

            $params = [
                'merchantCode' => $settings->merchant_code,
                'merchantOrderId' => $request->merchant_order_id,
            ];

            $params['signature'] = $settings->generateSignature($request->merchant_order_id);

            $response = \Http::post($apiUrl, $params);
            $result = $response->json();

            if (isset($result['statusCode'])) {
                $newStatus = DuitkuTransaction::mapDuitkuStatus($result['statusCode']);
                $oldStatus = $transaction->status;

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

                if (isset($result['reference'])) {
                    $transaction->update(['reference' => $result['reference']]);
                }

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

                    // Send broadcast notification if enabled
                    $settings = DuitkuSettings::first();
                    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 Duitku donation broadcast on check', [
                                'error' => $e->getMessage(),
                            ]);
                        }
                    }
                }
            }

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

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

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

        $settings = DuitkuSettings::first();

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

        try {
            // Call Duitku API to check transaction status
            $apiUrl = $settings->status_check_url;

            $params = [
                'merchantCode' => $settings->merchant_code,
                'merchantOrderId' => $transaction->merchant_order_id,
            ];

            $params['signature'] = $settings->generateSignature($transaction->merchant_order_id);

            $response = \Http::post($apiUrl, $params);
            $result = $response->json();

            if (isset($result['statusCode'])) {
                $newStatus = DuitkuTransaction::mapDuitkuStatus($result['statusCode']);
                $oldStatus = $transaction->status;

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

                if (isset($result['reference'])) {
                    $transaction->update(['reference' => $result['reference']]);
                }

                // 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 Duitku 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 Duitku 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()
    {
        // Based on Duitku API documentation: https://docs.duitku.com/api/id/#metode-pembayaran
        return [
            'va' => [
                'name' => 'Virtual Account',
                'channels' => [
                    'BC' => 'BCA Virtual Account',
                    'I1' => 'BNI Virtual Account',
                    'BR' => 'BRIVA (BRI Virtual Account)',
                    'M2' => 'Mandiri Virtual Account',
                    'VA' => 'Maybank Virtual Account',
                    'B1' => 'CIMB Niaga Virtual Account',
                    'BT' => 'Permata Bank Virtual Account',
                    'A1' => 'ATM Bersama',
                    'AG' => 'Bank Artha Graha',
                    'NC' => 'Bank Neo Commerce',
                    'S1' => 'Bank Sahabat Sampoerna',
                    'DM' => 'Danamon Virtual Account',
                    'BV' => 'BSI Virtual Account',
                ],
            ],
            'retail' => [
                'name' => 'Retail Store',
                'channels' => [
                    'FT' => 'Alfamart/Alfamidi',
                    'IR' => 'Indomaret',
                ],
            ],
            'ewallet' => [
                'name' => 'E-Wallet',
                'channels' => [
                    'OV' => 'OVO',
                    'DA' => 'DANA',
                    'LA' => 'LinkAja',
                    'SA' => 'ShopeePay',
                    'SP' => 'ShopeePay Apps',
                ],
            ],
            'qris' => [
                'name' => 'QRIS',
                'channels' => [
                    'NQ' => 'NOBU QRIS',
                    'SQ' => 'ShopeePay QRIS',
                ],
            ],
            'credit_card' => [
                'name' => 'Credit Card',
                'channels' => [
                    'VC' => 'Credit Card',
                ],
            ],
        ];
    }
}
