<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
use App\User;
use App\Models\Suppliers;
use App\Models\Payments;
use App\Models\FinishedContracts;
use App\Models\Cards;
use Openpay;
use Exception;
use OpenpayApiError;
use OpenpayApiAuthError;
use OpenpayApiRequestError;
use OpenpayApiConnectionError;
use OpenpayApiTransactionError;

require_once '../vendor/autoload.php';

class PaymentController extends Controller
{
    //


    public function index(Request $request)
    {
        //
        $request->session()->put('search', $request
              ->has('search') ? strip_tags($request->get('search')) : ($request->session()
              ->has('search') ? strip_tags($request->session()->get('search')) : ''));

        $request->session()->put('field', $request
                ->has('field') ? strip_tags($request->get('field')) : ($request->session()
                ->has('field') ? strip_tags($request->session()->get('field')) : 'id'));

        $request->session()->put('sort', $request
                ->has('sort') ? strip_tags($request->get('sort')) : ($request->session()
                ->has('sort') ? strip_tags($request->session()->get('sort')) : 'asc'));

        //$headers = $request->get('header') != '' ? $request->get('header') : -1;

        $payments = new FinishedContracts();
        $payments = $payments->where('status_id', 3)->where('paid', false)->where('transaction_id', '!=', 'NO APPLY')
                        ->orderBy(strip_tags($request->session()->get('field')), strip_tags($request->session()->get('sort')))
                        ->paginate(10);

        if ($request->ajax()) {
            return view('payments.index', compact('payments'));
          } else {
            return view('payments.ajax', compact('payments'));
          }

    }

    public function cardsindex(Request $request)
    {
        //
        $request->session()->put('search', $request
              ->has('search') ? strip_tags($request->get('search')) : ($request->session()
              ->has('search') ? strip_tags($request->session()->get('search')) : ''));

        $request->session()->put('field', $request
                ->has('field') ? strip_tags($request->get('field')) : ($request->session()
                ->has('field') ? strip_tags($request->session()->get('field')) : 'id'));

        $request->session()->put('sort', $request
                ->has('sort') ? strip_tags($request->get('sort')) : ($request->session()
                ->has('sort') ? strip_tags($request->session()->get('sort')) : 'asc'));

        //$headers = $request->get('header') != '' ? $request->get('header') : -1;

        $cards= new Cards();
        $cards = $cards->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('token', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orderBy(strip_tags($request->session()->get('field')), strip_tags($request->session()->get('sort')))
                              ->paginate(10);

        if ($request->ajax()) {
            return view('cards.index', compact('cards'));
          } else {
            return view('cards.ajax', compact('cards'));
          }

    }

    public function destroy($id)
    {
      $credit_card = Cards::where('id', $id)->first();
      $user = User::where('id', $credit_card->user_id)->first();
      Openpay::setProductionMode(true);

        try {
          $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
          $customer = $openpay->customers->get($user->openpay_id);
          $card = $customer->cards->get($credit_card->token);
          $card->delete();
        } catch (OpenpayApiTransactionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error en la transacción'
          ]);
        } catch (OpenpayApiRequestError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error en los datos requeridos'
          ]);
        } catch (OpenpayApiConnectionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);
        } catch (OpenpayApiAuthError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);

        } catch (OpenpayApiError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);
        } catch (Exception $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error: ' . $e->getMessage()
          ]);
        }

        Cards::destroy($id);
      return redirect('cards');
    }

    public function addcard(Request $request)
    {
      $rules = [
        'token' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
        'device_id' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
      ];

      $validator = Validator::make($request->all(), $rules);
      if ($validator->fails()) {
        return redirect()->back()->withInput($request->all())->withErrors($validator);
      }

      $user = $request->user();
      Openpay::setProductionMode(true);

        if ($user->openpay_id == null) {
          try {
            $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
            $customerData = array(
               'external_id' => $user->id,
               'name' => $user->name,
               'email' => $user->email,
            );
            $customer = $openpay->customers->add($customerData);
          } catch (OpenpayApiTransactionError $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'No se pudo procesar la transacción'
            ]);
          } catch (OpenpayApiRequestError $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'No se pudo procesar la operación'
            ]);
          } catch (OpenpayApiConnectionError $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
            ]);

          } catch (OpenpayApiAuthError $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
            ]);

          } catch (OpenpayApiError $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
            ]);
          } catch (Exception $e) {
            return response()->json([
              'type' => 'error',
              'message' => 'Error: ' . $e->getMessage()
            ]);
          }

        $user->openpay_id = $customer->id;
        $user->save();

        }


      $cardDataRequest = array(
        'token_id' => $request->token,
        'device_session_id' => $request->device_id
      );

      try {
        $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
        $customer = $openpay->customers->get($user->openpay_id);
        $card = $customer->cards->add($cardDataRequest);

      } catch (OpenpayApiTransactionError $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'No se pudo procesar la transacción'
        ]);
      } catch (OpenpayApiRequestError $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'No se pudo procesar la operación'
        ]);
      } catch (OpenpayApiConnectionError $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
        ]);

      } catch (OpenpayApiAuthError $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
        ]);

      } catch (OpenpayApiError $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
        ]);
      } catch (Exception $e) {
        return response()->json([
          'type' => 'error',
          'message' => 'Error: ' . $e->getMessage()
        ]);
      }

      $card = new Cards();

      $card->user_id = $user->id;
      $card->token = $request->token;

      $card->save();

      return response()->json([
          'message' => 'Tarjeta guardada exitosamente'
      ]);
    }

    public function deletecard(Request $request)
    {
      $rules = [
        'card_id' => 'required|numeric',
      ];

      $validator = Validator::make($request->all(), $rules);
      if ($validator->fails()) {
        return redirect()->back()->withInput($request->all())->withErrors($validator);
      }

      $user = $request->user();
      $credit_card = Cards::where('id', $request->card_id)->first();
      Openpay::setProductionMode(true);


      if ($credit_card->user_id == $user->id) {
        try {
          $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
          $customer = $openpay->customers->get($user->openpay_id);
          $card = $customer->cards->get($credit_card->token);
          $card->delete();
        } catch (OpenpayApiTransactionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'No se pudo procesar la transacción'
          ]);
        } catch (OpenpayApiRequestError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'No se pudo procesar la operación'
          ]);
        } catch (OpenpayApiConnectionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);

        } catch (OpenpayApiAuthError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);

        } catch (OpenpayApiError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);
        } catch (Exception $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error: ' . $e->getMessage()
          ]);
        }

        Cards::destroy($request->card_id);

        return response()->json([
            'message' => 'Tarjeta eliminada exitosamente'
        ]);
      }
    }

    public function getcards(Request $request)
    {
      $user = $request->user();
      Openpay::setProductionMode(true);

      if ($user->openpay_id) {
        try {
          $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
          $customer = $openpay->customers->get($user->openpay_id);
        } catch (OpenpayApiTransactionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'No se pudo procesar la transacción'
          ]);
        } catch (OpenpayApiRequestError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'No se pudo procesar la operación'
          ]);
        } catch (OpenpayApiConnectionError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);

        } catch (OpenpayApiAuthError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);

        } catch (OpenpayApiError $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
          ]);
        } catch (Exception $e) {
          return response()->json([
            'type' => 'error',
            'message' => 'Error: ' . $e->getMessage()
          ]);
        }

        $cards = Cards::where('user_id', $user->id)->get();

        $cardsinfo = array();

        foreach ($cards as $credit_card) {
          $card = $customer->cards->get($credit_card->token);
          $cardinfo = array(
            'id' => $credit_card->id,
            'brand' => $card->brand,
            'card_number' => $card->card_number,
          );
          $cardsinfo[] = $cardinfo;
        }
        return response()->json($cardsinfo);
      }
    }

}
