<?php

namespace App\Http\Controllers\KelengkapanData;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

use GuzzleHttp\Client;
use Illuminate\Support\Facades\Storage;
use Log;
use DB;
use Exception;
use Carbon\Carbon;
use Maatwebsite\Excel\Facades\Excel;

use App\Models\KelengkapanData\KelengkapanData;
use App\Http\Controllers\RegistrationCapelController;
use App\Exports\KelengkapanDataExport;
use App\Jobs\KelengkapanDataCrmJob;
use App\Helpers\GaClient;

class KelengkapanDataController extends Controller
{

    const DEFAULT_PER_PAGE = 10;

    public function __construct()
    {
        
    }

    public function verifikasiId(Request $request)
    {
        try {
            validation($request, [
                'reference_id' => 'required|'.regexValidString()
            ]);
        } catch (ValidationException $e) {
            Log::error('KelengkapanDataController - verifikasiId - validasi : '. json_encode($e->validator->errors()));
            return response()->json([
                'status' => false,
                'message' => 'Failed validation',
                'errors' => $e->validator->errors()
            ], 422);
        }

        try {
            
            $client = new Client(['verify' => false]);
            $url = env('CRM_GET_PROFILE', '');

            $headers = [
                'Ocp-Apim-Trace' => true,
                'PGN-Key' => env('CRM_PGN_KEY', '')
            ];

            $payload = [
                'headers' => $headers,
                'json' => [
                    'P_CUST_NUMBER' => substr($request->reference_id, 0, -3)
                ]
            ];
            
            Log::info('KelengkapanDataController - verifikasiId payload : '.json_encode($payload));

            $response = $client->request('POST', $url, $payload);

            $result = json_decode((string)$response->getBody());

            if (
                    $response->getStatusCode() == 200 && 
                    $result->CustProfileDataOutput[0] != null &&
                    isset($result->CustProfileDataOutput[0]->CUST_NAME)
                ) {
                
                if (substr(strtolower($result->CustProfileDataOutput[0]->CUST_NAME), 0, 3) == substr(strtolower($request->reference_id), -3)) {
                    
                    return response()->json([
                        'status' => true,
                        'message' => 'Berhasil Verifikasi Id',
                        'data' => $result->CustProfileDataOutput[0]
                    ], 200);

                }
                
                return response()->json([
                    'status' => false,
                    'message' => 'Data tidak ditemukan',
                    'data' => []
                ], 400);

            } else {
                return response()->json([
                    'status' => false,
                    'message' => 'Data tidak ditemukan',
                    'data' => []
                ], 400);
                Log::error('KelengkapanDataController - verifikasiId failed : '.json_encode($result));
            }

        } catch (Exception $e) {
            Log::error('KelengkapanDataController - verifikasiId : '. $e->getMessage());
            return response()->json([
                'status' => false,
                'message' => 'Gagal menghubungkan ke server'
            ], 500);
        }
    }

    public function update(Request $request)
    {
        try {
            validation($request, [
                'nama_pelanggan' => 'required|'.regexValidString(),
                'customer_id' => 'required|numeric',
                'provinsi' => 'required|numeric|exists:geo_provinces,id,is_deleted,0',
                'kota' => 'required|numeric|exists:geo_towns,id,is_deleted,0',
                'is_pk' => 'required|numeric|in:0,1',
                'is_badan_hukum' => 'required|numeric|in:0,1',
                'is_npwp' => 'required|numeric|in:0,1',
                'npwp' => 'required|'.regexValidNumber().'|min:14|max:16',
                'ktp' => 'required|'.regexValidNumber().'|min:14|max:16',
                'ktp_file' => 'required|image|mimes:jpeg,png,jpg|max:5000',
                'nama_ktp' => 'required|'.regexValidString(),
                'alamat_ktp' => 'required|'.regexValidString(),
                'alamat_lokasi_pemasangan' => 'required|'.regexValidString(),
                'no_telpon' => 'required|'.regexValidPhone().'|min:11|max:16',
                'email' => 'required|email'
            ]);
        } catch (ValidationException $e) {
            Log::error('KelengkapanDataController - update - validasi : '. json_encode($e->validator->errors()));
            return response()->json([
                'status' => false,
                'message' => 'Failed validation',
                'errors' => $e->validator->errors()
            ], 422);
        }

        DB::beginTransaction();
        try {

            // SAVE FILE TEMPORARY
            if (!Storage::exists('public/file_upload')) {
                Storage::makeDirectory('public/file_upload');
            }
            
            $path_ktp = "";
            if ($request->has('ktp_file')) {
                $path_ktp = $request->file('ktp_file')->store('file_upload', 'public');
            }
            // END SAVE FILE TEMPORARY

            $KelengkapanData = KelengkapanData::updateOrCreate(
                ['customer_id' => $request->customer_id],
                [
                    'nama_pelanggan' => $request->nama_pelanggan,
                    'geo_province_id' => $request->provinsi,
                    'geo_town_id' => $request->kota,
                    'is_pk' => $request->is_pk,
                    'is_badan_hukum' => $request->has('is_badan_hukum') ? $request->is_badan_hukum : null,
                    'is_npwp' => $request->is_npwp,
                    'npwp' => $request->npwp,
                    'ktp' => $request->ktp,
                    'ktp_url' => $path_ktp,
                    'nama_ktp' => $request->nama_ktp,
                    'alamat_ktp' => $request->alamat_ktp,
                    'alamat_lokasi_pemasangan' => $request->alamat_lokasi_pemasangan,
                    'no_telpon' => $request->no_telpon,
                    'email' => $request->has('email') ? $request->email : null 
                ]
            );
            
            DB::commit();

            KelengkapanDataCrmJob::dispatch($KelengkapanData);

            return response()->json([
                'status' => true,
                'message' => 'Berhasil memperbarui data',
                'data' => []
            ], 200);
        } catch (Exception $e) {
            DB::rollBack();

            Log::error('KelengkapanDataController - update : '. $e->getMessage());
            return response()->json([
                'status' => false,
                'message' => 'Gagal menghubungkan ke server'
            ], 500);
        }
    }

    public static function callApiUpdateProfile($data)
    {
        DB::beginTransaction();
        try {
            // UPLOAD KTP
            $folder = storage_path('app/public/');
            $ktp_url = $folder . $data->ktp_url;
            
            $idcard_url = "";
            
            if ($data->ktp_url != null && $data->ktp_url != "") {
                if ($data->ktp_url_relyon == null || $data->ktp_url_relyon == "") {
                    if (Storage::exists('public/'.$data->ktp_url)) {
                        $originalName = pathinfo(Storage::get($ktp_url), PATHINFO_FILENAME);
                        $originalExtension = pathinfo(Storage::get($ktp_url), PATHINFO_EXTENSION);
                        
                        $idcard_url = (new RegistrationCapelController)->uploadFile(env('RELYON_UPLOAD_ID_CARD'), fopen($ktp_url, 'r'), $originalName, $originalExtension);
        
                        if ($idcard_url != "") {
                            $data->ktp_url_relyon = $idcard_url;
                            $data->save();
                            DB::commit();
                        }
                    }
                } else {
                    $idcard_url = $data->ktp_url_relyon;
                }
            }
            // END UPLOAD KTP

            if ($idcard_url != "") {
                $client = new Client(['verify' => false]);
                $url = env('CRM_UPDATE_PROFILE', '');
    
                $headers = [
                    'Ocp-Apim-Trace' => true,
                    'PGN-Key' => env('CRM_PGN_KEY', '')
                ];
    
                $payload = [
                    'headers' => $headers,
                    'json' => [
                        'CUSTNUMBER' => $data->customer_id,
                        'NIK' => isset($data->ktp) && !empty($data->ktp) ? $data->ktp : '',
                        'NPWP' => isset($data->npwp) && !empty($data->npwp) ? $data->npwp : '',
                        'MEDIAINFORMASI' => '',
                        'NIKNPWPADDRESS' => isset($data->alamat_ktp) && !empty($data->alamat_ktp) ? $data->alamat_ktp : '',
                        'EMAIL' => isset($data->email) && !empty($data->email) ? $data->email : '',
                        'MOBILEPHONE' => isset($data->no_telpon) && !empty($data->no_telpon) ? $data->no_telpon : '',
                        'USERNAME' => ''
                    ]
                ];
                
                Log::info('KelengkapanDataController - callApiUpdateProfile payload : '.json_encode($payload));
    
                $response = $client->request('POST', $url, $payload);
                $result = json_decode((string)$response->getBody());
                
                Log::info('KelengkapanDataController - callApiUpdateProfile response : '.json_encode($result));
    
                if ($response->getStatusCode() == 200 && $result->STATUS === "SUCCESS") {

                    $temp_data = KelengkapanData::find($data->id);

                    $temp_data->update([
                        'is_send' => 1
                    ]);

                    DB::commit();

                    Log::error('KelengkapanDataController - callApiUpdateProfile success : '.json_encode($result));

                    return [
                        'sukses' => true,
                        'data' => $result
                    ];
                } else {
                    Log::error('KelengkapanDataController - callApiUpdateProfile failed : '.json_encode($result));
                    return [
                        'sukses' => false,
                        'data' => []
                    ];
                }
            }
            
            Log::error('KelengkapanDataController - callApiUpdateProfile gagal upload ktp');
            return [
                'sukses' => false,
                'data' => []
            ];

        } catch (Exception $e) {
            Log::error('KelengkapanDataController - callApiUpdateProfile : '. $e->getMessage());
            return [
                'sukses' => false,
                'data' => []
            ];
        }
    }

    // BACKOFFICE

    private function buildSearch($data, Request $request)
    {
        $data = $data->where('customer_id', 'like', '%'.$request->search.'%')
                ->orWhere('nama_pelanggan', 'like', '%'.$request->search.'%')
                ->orWhere('no_telpon', 'like', '%'.$request->search.'%')
                ->orWhere('email', 'like', '%'.$request->search.'%');

        return $data;
    }

    public function indexLog(Request $request)
    {
        try {
            validation($request, [
                'page' => 'required|numeric',
                'perPage' => 'required|numeric',
                'search' => regexValidString()
            ]);
        } catch (ValidationException $e) {
            Log::error('KelengkapanDataController - indexLog - validasi : '. json_encode($e->validator->errors()));
            return response()->json([
                'status' => false,
                'message' => 'Failed validation',
                'errors' => $e->validator->errors()
            ], 422);
        }

        try {

            $perPage = self::DEFAULT_PER_PAGE;
            
            $KelengkapanData = KelengkapanData::query();
            
            if ($request->has('perPage')) {
                $perPage = $request->perPage;
            }
            if ($request->has('search')) {
                $KelengkapanData = $this->buildSearch($KelengkapanData, $request);
            }

            $KelengkapanData = $KelengkapanData->orderBy('created_at', 'DESC');
            $KelengkapanData = $KelengkapanData->paginate($perPage);
            
            return response()->json([
                'status' => true,
                'message' => 'Berhasil mengambil data',
                'data' => $KelengkapanData
            ], 200);

        } catch (Exception $e) {
            Log::error('KelengkapanDataController - indexLog : '. $e->getMessage());
            return response()->json([
                'status' => false,
                'message' => 'Gagal menghubungkan ke server'
            ], 500);
        }
    }

    public function exportLog(Request $request)
    {
        return Excel::download(new KelengkapanDataExport($request), 'kelengkapan-data-log.xlsx');
    }

    public function syncLog(Request $request, GaClient $GaClient)
    {
        try {
            validation($request, [
                'id' => 'required|numeric|exists:kelengkapan_data,id'
            ]);
        } catch (ValidationException $e) {
            Log::error('KelengkapanDataController - syncLog - validasi : '. json_encode($e->validator->errors()));
            return response()->json([
                'status' => false,
                'message' => 'Failed validation',
                'errors' => $e->validator->errors()
            ], 422);
        }

        try {

            $KelengkapanData = KelengkapanData::find($request->id);

            if ($KelengkapanData->is_send === 1 && $KelengkapanData->is_send_email === 1) {
                return response()->json([
                    'status' => false,
                    'message' => 'Data sudah tersinkronisasi & terkirim email'
                ], 400);    
            }

            $is_send_crm = false;
            $is_send_email = false;

            if ($KelengkapanData->is_send === 0) {
                $sync_data = (new KelengkapanDataController)->callApiUpdateProfile($KelengkapanData);
    
                if ($sync_data['sukses']) {
                    $is_send_crm = true;
                }
            } else {
                $is_send_crm = true;
            }

            if ($is_send_crm) {

                if (!empty($KelengkapanData->email) && $KelengkapanData->email != "") {
                    $to = $KelengkapanData->email;
                    $subject = 'Konfirmasi Kelengkapan Data Pelanggan PGN';
                    $body = '';

                    $year = date("Y");

                    $html = view('mail.crm_pelanggan_email', [
                        'data' => $KelengkapanData,
                        'year' => $year,
                    ])->render();

                    $body = $html;
    
                    $response_ga = $GaClient->sendEmail($to, $subject, $body, []);

                    if ($response_ga) {
                        KelengkapanData::where('id', $request->id)
                        ->update([
                            'is_send_email' => 1
                        ]);

                        $is_send_email = true;

                        return response()->json([
                            'status' => true,
                            'message' => 'Berhasil sinkronisasi data & kirim email ke pelanggan'
                        ], 200);
                    }
                    
                }

                return response()->json([
                    'status' => true,
                    'message' => 'Berhasil sinkronisasi data'
                ], 200);

            }

            return response()->json([
                'status' => false,
                'message' => 'Gagal sinkronisasi data'
            ], 400);

        } catch (Exception $e) {
            Log::error('KelengkapanDataController - syncLog : '. $e->getMessage());
            return response()->json([
                'status' => false,
                'message' => 'Gagal menghubungkan ke server'
            ], 500);
        }
    }
}
