<?php

namespace App\Http\Controllers;

use App\Http\Support\ValidationRule;
use App\Jobs\SendMail;
use App\Models\Anggota;
use App\Models\Kegiatan;
use App\Models\KegiatanPeserta;
use App\Models\Konferensi;
use App\Models\Registrasi;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\MultipartStream;
use Illuminate\Contracts\Routing\Registrar;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use RealRashid\SweetAlert\Facades\Alert;
use Illuminate\Support\Str;
use function PHPUnit\Framework\isEmpty;

class RegistrasiController extends Controller
{
    public function create(){
        $kegiatan = Kegiatan::orderBy('id')->get();
        $konferensi = Konferensi::get();
        $date = Date('Y-m-d');

        $dataUniv = json_decode($this->getDataUniv(), true);
        foreach($dataUniv as $univ){
            if($univ['id_wil'] != '999999'){
                $universitas[] = [
                    'id_sp' => $univ['id_sp'],
                    'nm_lemb' => $univ['nm_lemb']
                ];
            }
        }

        // $lastKode = Registrasi::query()->whereDate('created_at', $date)->max('kode_registrasi');
        // $nourut = sprintf("%05s", ((int) substr($lastKode, -5))+1);
        // $tgldaftar = Carbon::now()->format('d-m-Y');
        // $komponen = explode('-', $tgldaftar);
        // $kode_registrasi = $komponen[0].$komponen[1].$nourut;

        $data = [
            'kegiatan' => $kegiatan,
            'konferensi' => $konferensi,
            'universitas' => $universitas
            // 'kode_registrasi' => $kode_registrasi
        ];

        return view('form_registrasi', $data);
    }

    public function group_create(){
        $dataUniv = json_decode($this->getDataUniv(), true);
        foreach($dataUniv as $univ){
            if($univ['id_wil'] != '999999'){
                $universitas[] = [
                    'id_sp' => $univ['id_sp'],
                    'nm_lemb' => $univ['nm_lemb']
                ];
            }
        }

        $data = [
            'universitas' => $universitas
        ];

        return view('form_registrasi_kelompok', $data);
    }

    public function group_kegiatan(Request $request){
        $rules = [
            'nama' => 'required|string',
            'email' => 'required|email:rfc,dns',
            'telepon' => 'required|numeric',
            'instansi' => 'required|string',
            'jabatan' => 'required|string',
            'alamat' => 'required|string',
            'kode_pos' => 'required|string',
            'kota' => 'required|string',
            'nik' => 'required|unique:registrasi,nik'
        ];

        $request->validate($rules, ValidationRule::getErrorMessage($rules));

        $kegiatan = Kegiatan::orderBy('id')->get();
        $konferensi = Konferensi::get();

        $data = [
            'kegiatan' => $kegiatan,
            'konferensi' => $konferensi,
            'data_registrasi' => $request->except('_token'),
        ];

        return view('form_kegiatan_kelompok', $data);
    }

    public function preview(Request $request){

        //cek jika kelompok atau tidak
        if(is_null($request->data_registrasi)){
            $rules = [
                'nama' => 'required|string',
                'email' => 'required|email:rfc,dns',
                'telepon' => 'required|numeric',
                'instansi' => 'required|string',
                'jabatan' => 'required|string',
                'alamat' => 'required|string',
                'kode_pos' => 'required|string',
                'kota' => 'required|string',
            ];
            $request->validate($rules, ValidationRule::getErrorMessage($rules));
        }

        DB::beginTransaction();

        try{
            $date = Date('Y-m-d');
            // $lastKode = Registrasi::query()->whereDate('created_at', $date)->max('kode_registrasi');
            // $nourut = sprintf("%05s", ((int) substr($lastKode, -5))+1);
            // $tgldaftar = Carbon::now()->format('d-m-Y');
            // $komponen = explode('-', $tgldaftar);
            // $kode_registrasi = $komponen[0].$komponen[1].$nourut;

            $urutanTerakhir = Registrasi::query()->max('urutan');
            $urutan = (int) $urutanTerakhir + 1;
            $nourut = sprintf("%05s", $urutan);
            $kode_registrasi = $nourut;

            if(!is_null($request->data_registrasi)){
                $registrasi = json_decode(decrypt($request->data_registrasi), true);
                $registrasi['kode_registrasi'] = $kode_registrasi;
                $registrasi['urutan'] = $urutan;
            }
            else{
                $registrasi = [
                    'nama' => strip_tags($request->nama),
                    'email' => strip_tags($request->email),
                    'telepon' => strip_tags($request->telepon),
                    'instansi' => strip_tags($request->instansi),
                    'jabatan' => strip_tags($request->jabatan),
                    'alamat' => strip_tags($request->alamat),
                    'kode_pos' => strip_tags($request->kodepos),
                    'kota' => strip_tags($request->kota),
                    'kode_registrasi' => strip_tags($kode_registrasi),
                    'urutan' => $urutan,
                    'nik' => strip_tags($request->nik)
                ];
            }

            $tglRegistrasi = Carbon::now()->format('Y-m-d h:i:s');
            $konaspi = Kegiatan::query()->where('id', '498633a9-082c-4a4a-9dbd-e20b678ec15e')->first();

            //inisial harga
            $totalHarga = (int) $konaspi->harga;

            if($request->konferensi[0] != null || $request->kegiatan[0] != "498633a9-082c-4a4a-9dbd-e20b678ec15e"){
                $i = 0;
                foreach($request->konferensi as $kon){
                    $daftarKonferensi[] = $kon;
                    $konferensi = Konferensi::query()->where('id', $kon)->first();

                    $daftarKegiatan[] = $request->kegiatan[$i];
                    $kegiatan[] = Kegiatan::select('id', 'nama', 'harga')->where('id', $request->kegiatan[$i])->first();
                    $indexAnggota = isset($request->kegiatan_anggota[$i]) ? $request->kegiatan_anggota[$i] : null;
                    $kegiatanAnggota = !is_null($indexAnggota) ? $request->anggota[$indexAnggota] : [];

                    if(!empty($kegiatanAnggota)){
                        $kegiatanAnggota['key'] = $request->kegiatan_anggota[$i];
                    }

                    $kegiatanpeserta[] = [
                        'id_kegiatan' => $kegiatan[$i]['id'],
                        'id_konferensi' => $daftarKonferensi[$i],
                        'nama_kegiatan' => $kegiatan[$i]['nama'],
                        'nama_konferensi' => $konferensi->nama,
                        'harga' => $kegiatan[$i]['harga'],
                        'anggota' => $kegiatanAnggota
                    ];

                    $hargaKonferensi[] = [
                        'idkon' => $konferensi->id,
                        'namakon' => $konferensi->nama,
                        'hargakon' => $konferensi->harga,
                        'namakeg' => $kegiatan[$i]['nama'],
                        'anggota' => $kegiatanAnggota
                    ];

                    // $totalHarga += (int) $konferensi->harga;
                    $i++;
                }
            }
            else{
                $kegiatan = Kegiatan::select('id', 'nama', 'harga')->where('id', $request->kegiatan[0])->first();
                $hargaKonferensi = null;
                $kegiatanpeserta[] = [
                    'id_kegiatan' => $request->kegiatan[0],
                    'id_konferensi' => null,
                    'nama_kegiatan' => $kegiatan->nama
                ];
            }

            $data = [
                'registrasi' => $registrasi,
                'kegiatanpeserta' => $kegiatanpeserta,
                'tglRegistrasi' => $tglRegistrasi,
                'konaspi' => $konaspi,
                'hargaKonferensi' => $hargaKonferensi,
                'totalHarga' => $totalHarga,
                'anggota' => $request->anggota ?? [],
                'kegiatan_anggota' => $request->kegiatan_anggota
            ];

            return view('preview', $data)->with('success', 'Data saved successfully');

        }
        catch(Exception $e){
            Log::error($e);
            DB::rollBack();

            return redirect()->back()
                ->with('error', 'Data failed to save');
        }
    }

    public function store(Request $request) {
        DB::beginTransaction();

        try{
            $registrasi = json_decode($request->registrasi, true);
            $kegiatanpeserta = json_decode($request->kegiatanpeserta, true);
            $konaspi = json_decode($request->konaspi, true);
            $hargaKonferensi = json_decode($request->hargaKonferensi, true);
            $anggota = json_decode($request->anggota, true);
            $tglRegistrasi = $request->tglRegistrasi;
            // $totalHargas = $request->totalHarga;
            $kegiatan_anggota = json_decode($request->kegiatan_anggota);
            $registrasi = Registrasi::query()->create($registrasi);
            $id_registrasi = $registrasi->id;
            $jumlahKeg = count($kegiatanpeserta);

            //anggota
            foreach($anggota as $key => $item){
                $anggota[$key]['id'] = Str::uuid()->toString();
                $anggota[$key]['id_registrasi'] = $id_registrasi;
                $anggota[$key]['created_at'] = Carbon::now()->toDateTimeString();
                $anggota[$key]['updated_at'] = Carbon::now()->toDateTimeString();
            }

            Anggota::query()->insert($anggota);

            //inisial harga
            $konvensi = Kegiatan::find($konaspi['id']);
            $konv = $konvensi->toArray();
            $jumlahPeserta = count($anggota);

            if($jumlahPeserta > 0){
                $totalHarga = ((int) $konvensi->harga) * $jumlahPeserta;
            }
            else{
                $totalHarga = ((int) $konvensi->harga);
            }

            if(!isEmpty($anggota) && !is_null($kegiatan_anggota)){
                $anggotaIndices = array_keys($anggota);
                $kegiatanAnggotaValues = array_values($kegiatan_anggota);

                $konvensi_anggota = array_values(array_diff($anggotaIndices, $kegiatanAnggotaValues));

                if($konvensi_anggota){
                    foreach ($konvensi_anggota as $key => $value) {
                        $convention_only = [
                            'id_registrasi' => $anggota[$value]['id_registrasi'],
                            'id_kegiatan' => $konv['id'],
                            'id_konferensi' => null,
                            'id_anggota' => $anggota[$value]['id']
                        ];

                        KegiatanPeserta::query()->create($convention_only);
                    }
                }
            }

            foreach($kegiatanpeserta as $keg){
                $arrayKeg = $keg;

                if(isset($arrayKeg['anggota']['key'])){
                    $idPeserta = isset($anggota[$arrayKeg['anggota']['key']]['id']) ? $anggota[$keg['anggota']['key']]['id'] : null;
                }
                else{
                    $idPeserta = null;
                }

                $kegpeserta = [
                    'id_registrasi' => $id_registrasi,
                    'id_kegiatan' => $keg['id_kegiatan'],
                    'id_konferensi' => $keg['id_konferensi'],
                    'id_anggota' => $idPeserta
                ];

                KegiatanPeserta::query()->create($kegpeserta);

                if($keg['id_kegiatan'] != '498633a9-082c-4a4a-9dbd-e20b678ec15e'){
                    $konferensi = Konferensi::query()->where('id', $keg['id_konferensi'])->first();
                    $kegkonaspi = Kegiatan::find($keg['id_kegiatan']);
                    // $totalHarga += (int) $konferensi->harga;

                    $kegPeserta[] = [
                        'idkon' => $konferensi->id,
                        'namakon' => $konferensi->nama,
                        'hargakon' => $konferensi->harga,
                        'namakeg' => $kegkonaspi->nama
                    ];
                }
                else{
                    $kegPeserta = null;
                }
            }

            $namanya = str_replace(["'", ".", ",", "-"], '', $registrasi['nama']);
            $nama = Str::substr($namanya, 0, 30);

            $multipartData = [
                'noid' => $registrasi['kode_registrasi'],
                'nama' => $nama,
                'tagihan' => $totalHarga
            ];

            $registrasi->save();

            $generatedVa = $this->generateVa($multipartData);
            $arrResponse = json_decode($generatedVa, true);
            $registrasi['status_va'] = $arrResponse['BTNresponse'];
            $registrasi['tagihan'] = $totalHarga;
            $registrasi['nomor_va'] = $arrResponse['BTNVirtualAccount'];

            $registrasi->save();

            if($arrResponse['BTNresponse'] != 'Request has been processed successfully'){
                DB::rollBack();
                Log::error('---');
                Log::error($multipartData);
                Log::error($arrResponse['BTNresponse']);
                Log::error('---');

                return redirect()->route('user.create')
                ->with('error', 'Data failed to save');
            }

            DB::commit();

            $data = [
                'registrasi' => $registrasi,
                'tglRegistrasi' => $tglRegistrasi,
                'konaspi' => $konv,
                'hargaKonferensi' => $kegPeserta,
                'totalHarga' => $totalHarga,
                'jumlah_peserta' => $jumlahPeserta,
                'kegiatanpeserta' => $kegiatanpeserta
            ];

            SendMail::dispatch($data, 'email.invoice', $data['registrasi']['email'], 'registrasi', 'email_regis_sent_at');

            return view('invoice', $data)->with('success', 'Data saved successfully');

        }
        catch(Exception $e){
            Log::error($e);
            DB::rollBack();

            return redirect()->route('user.create')
                ->with('error', 'Data failed to save');
        }
    }

    private function generateVa($multipartData)
    {
        $client = new Client();
        $options = [
            'form_params' => [
                // 'credential' => '$2a$08$xSX/XuObiJ3GoJWhjDTyXepT64o1ze.A/.OVYB15uzKW3V7pxgZ6O',
                'credential' => '$1$OkLGZt6i$FzuqzUwZ8nNS/xbzyPN/R/',
                'noid' => $multipartData['noid'],
                'nama' => $multipartData['nama'],
                'tagihan' => $multipartData['tagihan'],
                'flag' => 'F',
                'expired_date' => '2024-08-01T23:59:59+07:00',
                'deskripsi' => 'pembayaran konaspi'
            ]
        ];

        $response = $client->request('POST', 'https://neosidata.unesa.ac.id/btn_v2/create', $options);

        return $response->getBody()->getContents();
    }

    private function getDataUniv(){
        $client = new Client();
        $response = $client->request('GET', 'https://siakadu.unesa.ac.id/api/get_univ');

        return $response->getBody()->getContents();
    }

    public function addFormKegiatan(Request $request)
    {
        $data['kegiatan'] = Kegiatan::get();
        $data['konferensi'] = Konferensi::get();
        $data['i'] = $request->i;
        $data['anggota'] = $request->anggota;
        $data['list_anggota'] = $request->list_anggota;

        return view('form_kegiatan', $data);
    }

    public function addFormAnggota(Request $request)
    {
        $data['i'] = $request->i;
        $data['item'] = [
            'nama' => $request->nama,
            'email' => $request->email,
            'nik' => $request->nik,
            'telepon' => $request->telepon,
        ];

        return view('row_anggota', $data);
    }

    public function getDataRegis($va)
    {
        $registrasi = Registrasi::query()
        ->with('pkKegiatan', 'pkRegistrasiPeserta.rKegiatanPeserta', 'pkRegistrasiPeserta.rKonferensiPeserta', 'pkAnggota')
        ->where('nomor_va', $va)
        ->first();

        $jmlAnggota = count($registrasi->pkAnggota);

        $konvensi = Kegiatan::query()->find('498633a9-082c-4a4a-9dbd-e20b678ec15e');
        $konv = $konvensi->toArray();
        $totalHarga = $totalHarga = (int) $konvensi->harga;

        if($jmlAnggota != 0){
            $totalHarga = ((int) $konvensi->harga) * $jmlAnggota;
        }

        $kegPeserta = [];

        foreach($registrasi->pkRegistrasiPeserta as $item){

            if(is_null($item->rKonferensiPeserta)){
                continue;
            }

            $konferensi = $item->rKonferensiPeserta;
            $kegkonaspi = $item->rKegiatanPeserta;
            // $totalHarga += (int) $konferensi->harga;

            $kegPeserta[] = [
                'idkon' => $konferensi->id,
                'namakon' => $konferensi->nama,
                'hargakon' => $konferensi->harga,
                'namakeg' => $kegkonaspi->nama
            ];
        }

        $data = [
            'registrasi' => $registrasi,
            'tglRegistrasi' => $registrasi->created_at,
            'konaspi' => $konv,
            'hargaKonferensi' => $kegPeserta,
            'totalHarga' => $totalHarga,
            'jmlAnggota' => $jmlAnggota
        ];

        return $data;
    }

    public function updatePembayaran(Request $request, $va)
    {
        if($request->bearerToken() != 'zGKEX7CDNLOvVtetz6lqFZzhZv11Gr9Y2MKVIQmqusAyD5STPPEt7ZC1gl8P'){
            return response([
                'status' => 403,
                'message' => 'unauthorized access'
            ], 200);
        }

        try{
            $registrasi = Registrasi::query()
            ->with('pkKegiatan', 'pkRegistrasiPeserta.rKegiatanPeserta', 'pkRegistrasiPeserta.rKonferensiPeserta', 'pkAnggota')
            ->where('nomor_va', $va)
            ->update([
                'tanggal_bayar' => Carbon::now()
            ]);

            $data = $this->getDataRegis($va);

        SendMail::dispatch($data, 'email.selesai_pembayaran', $data['registrasi']->email, 'registrasi', 'email_pembayaran_sent_at');

            return response([
                'status' => 200,
                'message' => 'success'
            ], 200);
        }
        catch(Exception $ex){
            Log::error($ex);

            return response([
                'status' => 404,
                'message' => 'gagal mengupdate data'
            ], 200);
        }
    }

    public function testEmail(Request $request)
    {
        $data['registrasi'] = Registrasi::query()->where('kode_registrasi', '070300013')->first();

        SendMail::dispatch($data, 'email.invoice', $data['registrasi']->email, 'registrasi', 'email_regis_sent_at');
    }

    public function checkRegistrasi(Request $request, $va)
    {
        $data = $this->getDataRegis($va);

        return view('email.selesai_pembayaran', $data);
    }

    public function contact(){
        return view('contact');
    }
}

