<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use App\Models\Pembayaran;
use App\Models\Kategori;
use App\Models\Pembelian;
use App\Models\Layanan;
use App\Http\Controllers\VipResellerController;
use App\Http\Controllers\digiFlazzController;
use App\Http\Controllers\ApiGamesController;
use App\Http\Controllers\SmileOneController;

class TokoPayCallbackController extends Controller
{
    protected $url = 'https://api.tokopay.id/v1';
    
    public function __construct()
    {
        $api = \DB::table('setings')->where('id',1)->first();
        $this->MerchantID = $api->tokopay_merchantid;
        $this->SecretKey = $api->tokopay_secretkey;
    }

    public function handle(Request $request)
    {
        $json = $request->getContent();
        $data = json_decode($json);

        try {
            Storage::disk('local')->put('callback-tokopay.txt', $json);

            if (isset($data->status, $data->reff_id, $data->signature)) {
                // Validasi signature
                if ($data->signature !== md5($this->MerchantID . ":" . $this->SecretKey . ":" . $data->reff_id)) {
                    return Response::json(['error' => "Invalid Signature"])->setStatusCode(410);
                }

                // Cek status pembayaran
                if ($data->status === "Success") {
                    $order_id = $data->reff_id;
                    $pembayaran = Pembayaran::where('order_id', $order_id)->where('status', 'Belum Lunas')->first();
                    
                    if (! $pembayaran) {
                        return Response::json(['error' => 'No invoice found or already paid: ' . $order_id])->setStatusCode(440);
                    }

                    $dataPembeli = Pembelian::where('order_id', $order_id)->first();
                    if (! $dataPembeli) {
                        return Response::json(['error' => 'Pembelian tidak ditemukan: ' . $order_id])->setStatusCode(404);
                    }

                    $dataLayanan = Layanan::where('layanan', $dataPembeli->layanan)->first();
                    if (! $dataLayanan) {
                        return Response::json(['error' => 'Layanan tidak ditemukan: ' . $dataPembeli->layanan])->setStatusCode(404);
                    }

                    $dataKategori = Kategori::where('id', $dataLayanan->kategori_id)->first();
                    if (! $dataKategori) {
                        return Response::json(['error' => 'Kategori tidak ditemukan'])->setStatusCode(404);
                    }

                    $zoneSend = $dataPembeli->zone ? "(*$dataPembeli->zone*)" : "";
                    $nickname = $dataPembeli->nickname ? "❃ ➤ Nickname : $dataPembeli->nickname\n" : "";

                    $pesan = $this->formatPesanPembayaranBerhasil($dataPembeli, $dataLayanan, $dataKategori, $pembayaran, $zoneSend, $nickname, $order_id);
                    $pesanAdmin = $this->formatPesanAdminPembayaran($dataPembeli, $dataLayanan, $dataKategori, $pembayaran, $order_id);

                    $pembayaran->update(['status' => 'Lunas']);
                    $this->msg(ENV('NOMOR_ADMIN'), $pesanAdmin);
                    $this->msg($dataPembeli->no_pembeli, $pesan);

                    $this->prosesPesananKeProvider($dataPembeli, $dataLayanan, $order_id);
                    return Response::json(['status' => true])->setStatusCode(200);

                } elseif ($data->status === "Failed") {
                    $this->handlePembayaranGagal($data->reff_id);
                    return Response::json(['error' => "Status payment gagal"])->setStatusCode(420);
                } else {
                    $this->handlePembayaranGagal($data->reff_id);
                    return Response::json(['error' => "Status payment tidak valid"])->setStatusCode(420);
                }

            } else {
                return Response::json(['error' => "Data json tidak sesuai"])->setStatusCode(430);
            }

        } catch (\Exception $ex) {
            return Response()->json(['error' => $ex->getMessage()])->setStatusCode(500);
        }
    }

    private function formatPesanPembayaranBerhasil($dataPembeli, $dataLayanan, $dataKategori, $pembayaran, $zoneSend, $nickname, $order_id)
    {
        return "PEMBAYARAN BERHASIL\n" .
            "❍➤ Informasi pembelian\n" .
            "▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ \n" .
            "❃ ➤ ID Server :  *$dataPembeli->user_id* $zoneSend\n" .
            $nickname .
            "❃ ➤ Layanan :  *$dataKategori->nama*\n" .
            "❃ ➤ Produk : *$dataLayanan->layanan*\n" .
            "❃ ➤ Total Harga : *Rp. " . number_format($pembayaran->harga, 0, '.', ',') . "*\n" .
            "❃ ➤ Pembayaran : *$pembayaran->metode*\n" .
            "❃ ➤ Status : *Lunas*\n" .
            "❃ ➤ Nomor Invoice : *$order_id*\n\n" .
            "" . env("APP_URL") . "/pembelian/invoice/$order_id\n\n" .
            "Customer Support : " . ENV('NOMOR_ADMIN') . "\n" .
            "Online 24 Jam";
    }

    private function formatPesanAdminPembayaran($dataPembeli, $dataLayanan, $dataKategori, $pembayaran, $order_id)
    {
        return "*PEMBAYARAN BERHASIL #$order_id* TELAH LUNAS\n" .
            "❍➤ Informasi pembelian\n" .
            "▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ ▱ ▰ \n" .
            "❃ ➤ Tujuan : *$dataPembeli->user_id* (*$dataPembeli->zone*)\n" .
            "❃ ➤ Nickname : $dataPembeli->nickname\n" .
            "❃ ➤ Layanan :  *$dataKategori->nama*\n" .
            "❃ ➤ Produk : *$dataLayanan->layanan*\n" .
            "❃ ➤ Total Harga : *Rp. " . number_format($pembayaran->harga, 0, '.', ',') . "*\n" .
            "❃ ➤ Pembayaran : *$pembayaran->metode*\n" .
            "❃ ➤ Status : *Lunas*\n" .
            "❃ ➤ Nomor Invoice : *$order_id*\n" .
            "*Kontak Pembeli*\n" .
            "No HP : $pembayaran->no_pembeli";
    }

    private function prosesPesananKeProvider($dataPembeli, $dataLayanan, $order_id)
    {
        switch ($dataLayanan->provider) {
            case 'digiflazz':
               $digiFlazz = new digiFlazzController;
                                        $order = $digiFlazz->order($dataPembeli->user_id, $dataPembeli->zone, $dataLayanan->provider_id, $order_id);
                                        if ($order['data']['status'] == "Gagal") {
                                               $order['data']['status'] = false;
                                        } else {
                                            $order['transactionId'] = $order_id;
                                            $order['data']['status'] = true;
                                        }
                break;
            case 'vip':
                 $vip = new VipResellerController;
                                        $order = $vip->order($dataPembeli->user_id, $dataPembeli->zone, $dataLayanan->provider_id);
                                            
                                        if($order['result']){
                                            $order['data']['status'] = $order['result'];
                                            $order['transactionId'] = $order['data']['trxid'];
                                        }else{
                                            $order['data']['status'] = false;
                                        }
                break;
            case 'apigames':
               $apigames = new ApiGamesController;
                                        $order = $apigames->order($dataPembeli->user_id, $dataPembeli->zone, $dataLayanan->provider_id, $order_id);
                            
                                        if($order['data']['status'] == "Gagal"){
                                            $order['data']['status'] = false;
                                        }else{
                                            $order['transactionId'] = $order_id;
                                            $order['data']['status'] = true;
                                        }
                break;
                       case 'smileone':
                 $smileone = new SmileOneController;
                                        $order = $smileone->order($dataPembeli->user_id, $dataPembeli->zone, $dataLayanan->provider_id);
                            
                                        if($order['status'] != true){
                                            $order['data']['status'] = false;
                                            $note = $order['message'];
                                        }else{
                                            $order['transactionId'] = $order['transactionId'];
                                            $order['data']['status'] = true;
                                        }
                break;
            default:
                return Response::json(['error' => "Provider tidak dikenal."])->setStatusCode(400);
        }

       if ($order['data']['status']) { // Jika pembelian sukses
    $dataPembeli->update([
        'keterangan' => 'Sedang diproses...',
        'provider_order_id' => isset($order['transactionId']) ? $order['transactionId'] : null,
        'status' => 'Process',
        'log' => json_encode($order)
    ]);

    // Log untuk mencatat pembelian sukses
    Log::info('Pembelian sukses diproses untuk Order ID: ' . $order_id . ', Provider: ' . $dataLayanan->provider);

} else { // Jika pembelian gagal
    $dataPembeli->update([
        'status' => 'Batal',
        'log' => json_encode($order)
    ]);

    // Log kegagalan pesanan
    Log::error('Gagal memproses pesanan untuk Order ID: ' . $order_id . '. Detail: ' . json_encode($order));

    // Jika ingin menyimpan log lokal ke file khusus
    Storage::disk('local')->put('logs/provider-failures.txt', 
        '[' . now() . '] Gagal memproses pesanan untuk Order ID: ' . $order_id . 
        '. Provider: ' . $dataLayanan->provider . 
        '. Detail: ' . json_encode($order) . PHP_EOL, FILE_APPEND
    );
}
}

    private function handlePembayaranGagal($order_id)
    {
        $pembayaran = Pembayaran::where('order_id', $order_id)->first();
        if ($pembayaran && $pembayaran->status !== 'Lunas') {
            $pembayaran->update(['status' => 'Gagal']);
            $pembelian = Pembelian::where('order_id', $order_id)->first();
            if ($pembelian) {
                $pembelian->update(['status' => 'dibatalkan']);
            }
        }
    }

    private function msg($number, $message)
    {
         $api = \DB::table('setings')->where('id',1)->first();
        $curl = curl_init();
        curl_setopt_array($curl, array(
          CURLOPT_URL => 'https://api.fonnte.com/send',
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => '',
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 0,
          CURLOPT_FOLLOWLOCATION => true,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => 'POST',
          CURLOPT_POSTFIELDS => array('target' => $number,'message' => $message),
          CURLOPT_HTTPHEADER => array(
            'Authorization: '.$api->wa_key
          ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }
}

