<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Order;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\BalanceLog;
use App\Helpers\BalanceHelper;
use App\Helpers\WebhookHelper;
use App\Services\TelegramLogService;

class WebhookController extends Controller
{
    public function smscode(Request $request)
    {
        $payload = $request->getContent();
        $signature = $request->header('X-Webhook-Signature');

        // ❗ wajib ada signature
        if (!$signature) {
            return response()->json(['message' => 'Missing signature'], 400);
        }

        $secret = config('services.smscode.webhook_secret');
        $expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

        // ❗ validasi signature
        if (!hash_equals($expected, $signature)) {
            return response()->json(['message' => 'Invalid signature'], 403);
        }

        $json = $request->json()->all();

        Log::info('Webhook SMSCode', $json);

        $event = $json['event'] ?? null;
        $data  = $json['data'] ?? [];

        // ✅ handle test webhook
        if ($event === 'webhook.test') {
            return response()->json(['message' => 'Test OK']);
        }

        $orderId = $data['order_id'] ?? null;

        if (!$orderId) {
            return response()->json(['message' => 'No order_id'], 400);
        }

        $order = Order::where('order_id', $orderId)->first();

        if (!$order) {
            return response()->json(['message' => 'Order not found'], 404);
        }

        // 🔥 mapping status biar SAMA dengan OrderV2
        switch ($event) {

case 'order.otp_received':

DB::transaction(function () use ($order, $data) {

$o = Order::lockForUpdate()->find($order->id);

if (!$o) return;

// jangan proses kalau sudah refund
if ($o->refunded_at) return;

// hanya skip kalau memang sudah SUCCESS DAN OTP sudah tersimpan
if ($o->status === 'SUCCESS' && !empty($o->otp)) {
    return;
}

// simpan OTP jika ada
if (!empty($data['otp_code'])) {
    $o->otp = $data['otp_code'];
}

// pastikan status SUCCESS bila OTP sudah ada
if (!empty($o->otp)) {
    $o->status = 'SUCCESS';
}

Log::info('📱OTP WEBHOOK RECEIVED', [
    'local_order_id' => $o->id,
    'provider_order_id' => $o->order_id,
    'otp' => $data['otp_code'] ?? null,
    'status_before' => $o->status,
]);
$o->save();

// load relasi user
$o->load('user');

WebhookHelper::send($o->user, [
    'event' => 'otp.received',
    'data' => [
        'order_id' => $o->id,
        'otp_code' => $o->otp,
        'status'   => $o->status
    ]
]);

// ==========================
// TELEGRAM LOG
// ==========================
TelegramLogService::orderSuccess($o);

Log::info("OTP MASUK webhook order #{$o->id}");
});

break;
case 'order.completed':

DB::transaction(function () use ($order) {

    $o = Order::where('id', $order->id)
        ->lockForUpdate()
        ->first();

    if (!$o || $o->status !== "PENDING" || $o->refunded_at !== null) return;

    $o->update([
        'status' => 'SUCCESS',
    ]);
$user = User::find($o->user_id);

WebhookHelper::send($user, [
    'event' => 'order.success',
    'data' => [
        'order_id' => $o->id,
        'status'   => 'SUCCESS'
    ]
]);
});

break;

case 'order.expired':

DB::transaction(function () use ($order) {

    $o = Order::where('id', $order->id)
        ->lockForUpdate()
        ->first();

    if (!$o) return;

    // 🔥 TAMBAHAN DI SINI
    if ($o->otp) {
    Log::warning("EXPIRED tapi OTP sudah ada #{$o->id}");

    $user = User::find($o->user_id);

    WebhookHelper::send($user, [
        'event' => 'order.update',
        'data' => [
            'order_id' => $o->id,
            'status'   => $o->status,
            'note'     => 'expired_but_has_otp'
        ]
    ]);

    return;
}

    // 🔒 GUARD UTAMA
   // ✅ jangan double refund
if ($o->refunded_at !== null) return;

// 🚫 jangan refund kalau sudah sukses
if ($o->status === 'SUCCESS') return;

    $o->update([
        'status' => 'FAILED',
        'refunded_at' => now()
    ]);

    $user = User::find($o->user_id);

BalanceHelper::addLog(

    $user,
        'CREDIT',
        $o->harga,
        'Refund webhook smscode',
        $o->id
    );

WebhookHelper::send($user, [
    'event' => 'order.failed',
    'data' => [
        'order_id' => $o->id,
        'status'   => 'FAILED',
        'refund'   => (float) $o->harga,
        'reason'   => 'expired'
    ]
]);
    Log::warning("SAFE refund #{$o->id}");
});
break;

case 'order.canceled':

DB::transaction(function () use ($order) {

    $o = Order::where('id', $order->id)
        ->lockForUpdate()
        ->first();

    if (!$o) return;

if ($o->otp) {
    Log::warning("CANCEL tapi OTP sudah ada #{$o->id}");

    $user = User::find($o->user_id);

    WebhookHelper::send($user, [
        'event' => 'order.update',
        'data' => [
            'order_id' => $o->id,
            'status'   => $o->status,
            'note'     => 'canceled_but_has_otp'
        ]
    ]);

    return;
}
    // 🔒 GUARD UTAMA
   // ✅ jangan double refund
if ($o->refunded_at !== null) return;

// 🚫 jangan refund kalau sudah sukses
if ($o->status === 'SUCCESS') return;

    $o->update([
        'status' => 'CANCELED',
        'refunded_at' => now()
    ]);

    $user = User::find($o->user_id);

BalanceHelper::addLog(

    $user,
        'CREDIT',
        $o->harga,
        'Refund cancel smscode',
        $o->id
    );

WebhookHelper::send($user, [
    'event' => 'order.canceled',
    'data' => [
        'order_id' => $o->id,
        'status'   => 'CANCELED',
        'refund'   => (float) $o->harga
    ]
]);
    Log::warning("SAFE refund #{$o->id}");
});
break;


            default:
                // event lain diabaikan
                Log::warning('Unknown webhook event', ['event' => $event]);
                break;
        }

        return response()->json(['message' => 'OK']);
    }
}