<?php

namespace App\Http\Controllers\Legacy;

use App\Data\CheckingAccountData;
use App\Data\CheckingAccountForm;
use App\Data\InstallmentCheckingAccountForm;
use App\Data\SettlementForm;
use App\Http\Controllers\Controller;
use App\Http\Requests\PaymentRequest;
use App\Services\OraclePaymentService;
use Artisaninweb\SoapWrapper\Exceptions\ServiceAlreadyExists;
use Artisaninweb\SoapWrapper\SoapWrapper;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ServerException;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
use SoapFault;

class MainController extends Controller
{
    public function __construct(
        protected readonly OraclePaymentService $service,
        protected SoapWrapper $soapWrapper
    ) {}

    public function getIndex(): View
    {
        $sessionData = Session::get('Datos');
        $sessionId = $sessionData['codsesion'];
        $taxpayerId = $sessionData['codContri'];

        $formData_1 = CheckingAccountForm::from([
            'session' => $sessionId,
            'codcontri' => $taxpayerId,
            'anyo_ini' => (string) Carbon::now()->year,
            'anyo_fin' => (string) Carbon::now()->year,
            'codpredio' => '',
            'tributo' => '',
            'periodo_tipo' => '',
            'estado' => 'PEN',
        ]);

        $formData_2 = InstallmentCheckingAccountForm::from([
            'session' => $sessionId,
            'codcontri' => $taxpayerId,
            'anyo_ini' => '1900',
            'anyo_fin' => (string) Carbon::now()->year,
            'tipocontr' => '',
            'estado' => 'PEN',
        ]);

        $formData_3 = SettlementForm::from([
            'session' => $sessionId,
            'codcontri' => $taxpayerId,
            'fech_liquidacion_desde' => '01/01/1900',
            'fech_liquidacion_hasta' => '01/01/'.(string) Carbon::now()->year,
            'estado' => 'PEN',
        ]);

        /* @var Collection<CheckingAccountData> $result */
        $result = Cache::remember(
            key: 'LM_Cta_Cte_'.$taxpayerId,
            ttl: now()->addMinutes(5),
            callback: fn () => $this->service->checkingAccount($formData_1)
        );
        // $result = SOAP_WRAPPER($formData_1->toArray(), null, 'consultar_ctacte')

        $result2 = Cache::remember(
            key: 'LM_Cta_Cte_Frac_'.$taxpayerId,
            ttl: now()->addMinute(),
            callback: fn () => SOAP_WRAPPER($formData_2->toArray(), null, 'consultar_ctacte_fracc')
        );
        // $result2 = SOAP_WRAPPER($formData_2->toArray(), null, 'consultar_ctacte_fracc');

        $result3 = Cache::remember(
            key: 'LM_Settlement_'.$taxpayerId,
            ttl: now()->addMinute(),
            callback: fn () => SOAP_WRAPPER($formData_3->toArray(), null, 'listar_liquidaciones')
        );
        // $result3 = SOAP_WRAPPER($formData_3->toArray(), null, 'listar_liquidaciones');

        if ($result->isEmpty()) {
            $WSResult = [];
        } else {
            $WSResult = $result;
        }

        if ($result2 == null) {
            $WSResultF = [];
        } else {
            $WSResultF = $result2;
        }

        if ($result3 == null) {
            $WSResultL = [];
        } else {
            $WSResultL = $result3;
        }

        return view('pages.general', compact('WSResult', 'WSResultF', 'WSResultL'));
    }

    /*public function getViewer(){


        $numPedido = Session::get("liquidacion");

        $mount     = Session::get("importe");
        $mount     = number_format((float)$mount, 2, '.', '');

        $token  = generateToken();
        $sesion = generateSesion($mount, $token);
        $ETICKET = '3412312325'; // generatePurchaseNumber();

        echo  ' token '.$token ;
        echo  ' sesion '.$sesion ;
        echo  ' ETICKET '.$ETICKET ;

        Session::put("token",$token);
        Session::put("sesion",$sesion);
        Session::put("ETICKET",$ETICKET);
        /


      //  return view('pages.viewer');
       return view('pages.posttes');
    }*/

    public function postPayments(PaymentRequest $request)
    {
        $validated = $request->validated();

        $payarray = $validated['arraypay'];
        $payarray = substr($payarray, 0);

        $pTarraypay = $validated['Tarraypay'];
        $pTarraypay = substr($pTarraypay, 0, 1);

        if ($payarray != '') {
            try {
                $arr = [];
                $result = '';
                $codliqui = '';
                $Monto = 0.0;
                $aux = explode(',', $payarray);

                foreach ($aux as $i) {
                    $arr[] = ['item', 'ctaidentif' => $i];
                }

                $data = ['session' => Session::get('Datos')['codsesion'], 'listactaidentif' => $arr];

                switch ($pTarraypay) {
                    case 'L':
                        $consultaMonto = ['session' => Session::get('Datos')['codsesion'],
                            'codcontri' => Session::get('Datos')['codContri'],
                            'fech_liquidacion_desde' => '01/01/1990',
                            'fech_liquidacion_hasta' => '01/01/'.(string) Carbon::now()->year,
                            'estado' => 'PEN'];
                        $resulMonto = '';
                        $resulMonto = SOAP_WRAPPER($consultaMonto, $resulMonto, 'listar_liquidaciones');
                        break;
                    case 'I':
                        $result = SOAP_WRAPPER($data, $result, 'generar_liquidacion');
                        break;
                    case 'F':
                        $result = SOAP_WRAPPER($data, $result, 'generar_liquidacion');
                        break;
                }

                if (strcmp($pTarraypay, 'L') === 0) {
                    $result = $resulMonto;
                    usort($aux, 'strnatcmp');
                    foreach ($resulMonto as $list) {
                        if (in_array($list->liqnumero, $aux)) {
                            $codliqui = $list->liqnumero;
                            $Monto = $Monto + (float) $list->liqemitido;
                        }
                    }
                }

                if (strcmp($pTarraypay, 'I') === 0 || strcmp($pTarraypay, 'F') === 0) {
                    if (! strncmp($result['codmensaje'], 'EXITO ', 6)) {
                        Session::put('liquidacion', $result['operacion']);
                        Session::put('General', $result['cgonumero']);
                        Session::put('importe', $result['importe']);

                        return view('pages.viewer');
                    } else {
                        return redirect('/');
                    }
                } else {
                    if ($result != '') {
                        Session::put('liquidacion', $codliqui);
                        Session::put('General', $codliqui);
                        Session::put('importe', $Monto);

                        return view('pages.viewer');
                    } else {
                        return redirect('/');
                    }
                }
            } catch (ClientException) {
                return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el cliente');
            } catch (ServerException) {
                return redirect('oauth/login')->with('alert-danger', 'Ocurrió un error con el servidor');
            } catch (ConnectException) {
                return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el servidor');
            } catch (RequestException) {
                return redirect('oauth/login')->with('alert-danger', 'Request Exception error');
            }
        } else {
            return redirect('/')->with('alert-danger', 'Debe elegir al menos un item');
        }
    }

    /* public function postVisa(Request $request){

         /*if($request->session()->has('liquidacion') && $request->session()->has('importe')){
             $numPedido = $request->session()->get('liquidacion');
             $mount = $request->session()->get('importe');
             $mount = number_format((float)$mount, 2, '.', '');

             $token  = generateToken();
             $sesion = generateSesion($mount, $token);
             //$ETICKET = '3400000000';//'3412312324'; // generatePurchaseNumber();

             $html = htmlRedirecFormEticket_($numPedido, $sesion, $mount);
             echo $html;
             exit;
         }else
         {
             return redirect('/')->with('alert-danger','Debe seleccionar como mínimo una registro.');
         }
        // return view('/',compact('result'));




         /*if($request->session()->has('liquidacion') && $request->session()->has('importe')){
             $numPedido = $request->session()->get('liquidacion');
             $mount = $request->session()->get('importe');
             $mount = number_format((float)$mount, 2, '.', '');
             $xmlIn = "";
             $xmlIn = $xmlIn . "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
             $xmlIn = $xmlIn . "<nuevo_eticket>";
             $xmlIn = $xmlIn . " <parametros>";
             $xmlIn = $xmlIn . "     <parametro id=\"CANAL\">3</parametro>";
             $xmlIn = $xmlIn . "     <parametro id=\"PRODUCTO\">1</parametro>";
             $xmlIn = $xmlIn . "     ";
             $xmlIn = $xmlIn . "     <parametro id=\"CODTIENDA\">" .config('constants.COMMERCE_CODE'). "</parametro>";
             $xmlIn = $xmlIn . "     <parametro id=\"NUMORDEN\">" . $numPedido . "</parametro>";
             $xmlIn = $xmlIn . "     <parametro id=\"MOUNT\">" . $mount . "</parametro>";
             $xmlIn = $xmlIn . " </parametros>";
             $xmlIn = $xmlIn . "</nuevo_eticket>";


             SoapWrapper::add(function ($service) {
                 $service->name('SimiServices')->wsdl(config('constants.URL_WSGENERAETICKET_VISA'));
             });

             $data = ['xmlIn'=>$xmlIn];
             $result = '';

             SoapWrapper::service('SimiServices',function ($service) use ($data,&$result){
                 $result = $service->call('GeneraEticket',[$data]);
             });

             $xmlDocument = new \DOMDocument();

             if($xmlDocument->loadXML($result->GeneraEticketResult)){
                 $iCantMessage = CantidadMensajes($xmlDocument);
                 for($iNumMensaje=0;$iNumMensaje<$iCantMessage;$iNumMensaje++){
                    rror = RecuperaMensaje($xmlDocument, $iNumMensaje+1);
                     return redirect('/')->with('alert-danger',$error);
                 }
                 if($iCantMessage == 0){
                     $Eticket= RecuperaEticket($xmlDocument);
                     $html= htmlRedirecFormEticket($Eticket);
                     echo $html;
                     exit;
                 }

             }else{
                 return redirect('/')->with('alert-danger','Debe seleccionar como mínimo una registro.');
             }
         }else{
             return redirect('/')->with('alert-danger','Debe seleccionar como mínimo una registro.');
         }
         return view('/',compact('result'));
     }*/

    public function postResult(Request $request): View|RedirectResponse
    {
        $WSResult = [];

        if (! empty($request->eticket)) {
            $eTicket = $request->eticket;
            $codTienda = config('constants.COMMERCE_CODE');
            $xmlIn = generateXMLConsulta($codTienda, $eTicket);

            try {
                $wsdl = config('constants.URL_WSCONSULTAETICKET_VISA');

                $this->soapWrapper->add('SimiServices', fn ($service) => $service->wsdl($wsdl));

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

                $result = $this->soapWrapper->call('SimiServices.ConsultaEticket', [$data]);

                $xmlDocument = new \DOMDocument;

                if ($xmlDocument->loadXML($result->ConsultaEticketResult)) {
                    $iCantOpe = CantidadOperaciones($xmlDocument, $eTicket);

                    for ($iNumOperacion = 0; $iNumOperacion < $iCantOpe; $iNumOperacion++) {
                        $data = PresentaResultado($xmlDocument, $iNumOperacion + 1);

                    }

                    $WSResult = $data;
                    $iCantMensajes = CantidadMensajes($xmlDocument);

                    for ($iNumMensaje = 0; $iNumMensaje < $iCantMensajes; $iNumMensaje++) {
                        echo 'Mensaje #'.($iNumMensaje + 1).': ';
                        echo RecuperaMensaje($xmlDocument, $iNumMensaje + 1);
                        echo '<BR>';
                    }

                    session()->put('pdfdata', $data);

                    if ($data['estado'] == 'AUTORIZADO') {
                        try {
                            $data = ['operacion' => Session::get('liquidacion'),
                                'resp_transaccion' => 2,
                                'pagfechpag' => date('d/m/Y'),
                                'lgpcodigo' => 'B10'];
                            $result = '';
                            SOAP_WRAPPER($data, $result, 'registrar_pagoliquidacion');

                            return view('pages.result', compact('WSResult'));
                        } catch (ClientException) {
                            return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el cliente');
                        } catch (ServerException) {
                            return redirect('oauth/login')->with('alert-danger', 'Ocurrió un error con el servidor');
                        } catch (ConnectException) {
                            return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el servidor');
                        } catch (RequestException) {
                            return redirect('oauth/login')->with('alert-danger', 'Request Exception error');
                        }
                    }
                }
            } catch (ServiceAlreadyExists) {
                return redirect('/')->with('alert-danger', 'Error durante el registro del servicio.');
            } catch (SoapFault) {
                return redirect('/')->with('alert-danger', 'Error durante llamada al servicio.');
            }
        }

        return view('pages.result', compact('WSResult'));
    }

    public function PageHistorial(): JsonResponse|RedirectResponse
    {
        $sessionData = Session::get('Datos');
        $taxpayerId = $sessionData['codContri'];
        $data = ['codcontri' => $taxpayerId];

        $result = '';

        $cacheKey = 'LM_History_'.$taxpayerId;

        $result = Cache::remember(
            key: $cacheKey,
            ttl: now()->addMinute(),
            callback: fn () => SOAP_WRAPPER($data, $result, 'listar_pagos')
        );

        if (Session::Has('Estado')) {
            $WSHistoria['data'] = $result;

            return response()->json($WSHistoria);
        }

        $res = [];

        return redirect('oauth/login')->with('alert-danger', $res['error'].': '.$res['error_description']);
    }

    public function getHistorialPagos(): View
    {
        return view('pages.historial', [
            'result' => '',
        ]);
    }

    public function getRecibo($e)
    {
        try {
            $data = ['cgonumero' => $e];
            $result = '';
            $result = SOAP_WRAPPER($data, $result, 'listar_pagos_detalle');

            if (Session::Has('Estado')) {
                generateRecibo(true, $result);
            } else {
                $res = [];

                return redirect('oauth/login')->with('alert-danger', $res['error'].': '.$res['error_description']);
            }
        } catch (ClientException) {
            return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el cliente');
        } catch (ServerException) {
            return redirect('oauth/login')->with('alert-danger', 'Ocurrió un error con el servidor');
        } catch (BadResponseException) {
            return redirect('oauth/login')->with('alert-danger', 'Ocurrió un error en la respuesta');
        } catch (ConnectException) {
            return redirect('oauth/login')->with('alert-danger', 'Error de conexión con el servidor');
        } catch (RequestException) {
            return redirect('oauth/login')->with('alert-danger', 'Request Exception error');
        } catch (Exception) {
            return redirect('oauth/login')->with('alert-danger', 'Exception error');
        }
    }

    /*
    public function posttes() {
        $result = SOAP_WRAPPERx('respondio waaa ');
        $array = ['mensaje'=>$result];
        return view('pages.test', compact("array"));

        //include(app_path().'\Http\Controllers\PricesClass.php');
        //$pricesClass = new PricesClass();
        //$array = $pricesClass->getPrices();

        //$ret = hola_hola2();
        //$array = ['mensaje'=>$ret];
        //return view('pages.test', compact('array'));

        Session::put("aa","A1");
        Session::put("bb","A2");
        Session::put("cc","A3");

        return view('pages.test', compact('array'));
    }*/
}
