<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;
use Carbon\Carbon;
use OneSignal;
use Openpay;
use Exception;
use OpenpayApiError;
use OpenpayApiAuthError;
use OpenpayApiRequestError;
use OpenpayApiConnectionError;
use OpenpayApiTransactionError;
use App\iChambaParameter;
use App\Models\Suppliers;
use App\Models\Categories;
use App\Models\Cards;
use App\Models\Postulations;
use App\Models\CurrentContracts;
use App\Models\FinishedContracts;
use App\Models\Status;
use App\Models\Payments;
use App\Models\Coupon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Grimzy\LaravelMysqlSpatial\Types\Point;

class ContractController extends Controller
{
    //

    public function currentcontracts(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;

        $currentcontracts = new CurrentContracts();
        $currentcontracts = $currentcontracts->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('user_id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('address', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('amount', '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('currentcontracts.index', compact('currentcontracts'));
          } else {
            return view('currentcontracts.ajax', compact('currentcontracts'));
          }

    }

    public function mapcurrentcontracts(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;

        $currentcontracts = new CurrentContracts();
        $currentcontracts = $currentcontracts->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('user_id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('address', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('amount', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                        ->orderBy(strip_tags($request->session()->get('field')), strip_tags($request->session()->get('sort')))
                        ->paginate(10);

        return view('currentcontracts.map', compact('currentcontracts'));

    }

    public function finishedcontracts(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;

        $finishedcontracts = new FinishedContracts();
        $finishedcontracts = $finishedcontracts->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('user_id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('address', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('amount', '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('finishedcontracts.index', compact('finishedcontracts'));
          } else {
            return view('finishedcontracts.ajax', compact('finishedcontracts'));
          }

    }

    public function mapfinishedcontracts(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;

        $finishedcontracts = new FinishedContracts();
        $finishedcontracts = $finishedcontracts->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('user_id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('address', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                              ->orwhere('amount', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
                        ->orderBy(strip_tags($request->session()->get('field')), strip_tags($request->session()->get('sort')))
                        ->paginate(10);

        return view('finishedcontracts.map', compact('finishedcontracts'));

    }

    public function create(Request $request) {

      $rules = [
        'postulation_id' => 'required|numeric',
        'supplier_id' => 'required|numeric',
        'card_id' => 'required|numeric',
        'code' => 'required|numeric',
        'device_id' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
        'coupon' => 'nullable|string|regex:/(^[A-Za-z0-9 ]+$)+/',
      ];

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

        $user = Auth::user();
        $postulation = Postulations::where('id', $request->postulation_id)->first();
        $coupon = Coupon::where('name', $request->coupon)->first();
        Openpay::setProductionMode(true);

        if ($user->id == $postulation->user_id) {

          if ($request->card_id) {
            $card = Cards::where('id', $request->card_id)->first();
          }
          $supplier = Suppliers::where('id', $request->supplier_id)->first();

          $IVA = iChambaParameter::where('id', $supplier->IVA_id)->first();
          $ISR = iChambaParameter::where('id', $supplier->ISR_id)->first();

          $ichambafee =  iChambaParameter::where('parameter', 'ichamba_fee')->first();
          $category = Categories::where('id', $postulation->category_id)->first();

          if ($card->user_id == $user->id) {

            $contract = new CurrentContracts();
            $contract->user_id = $postulation->user_id;
            $contract->supplier_id = $supplier->id;
            $contract->category_id = $postulation->category_id;
            $contract->address = $postulation->address;
            $contract->location = $postulation->location;
            if (isset($postulation->int_number)) {
              $contract->int_number = $postulation->int_number;
            } else {
              $contract->int_number = 0;
            }
            $contract->references = $postulation->references;
            $contract->appointment = $postulation->appointment;
            $contract->amount = ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee);
            if (isset($IVA->num_value) && isset($IVA->num_value)) {
              $contract->IVA = $IVA->num_value;
              $contract->ISR = $ISR->num_value;
              $contract->revenue = ((($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee) * ((100 - $ichambafee->num_value) / 100)) * ((100 - $IVA->num_value - $ISR->num_value) / 100));
            } else {
              $contract->IVA = 0;
              $contract->ISR = 0;
              $contract->revenue = (($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee) * ((100 - $ichambafee->num_value) / 100));
            }
            $contract->ichamba_fee = $ichambafee->num_value;
            $contract->details = $postulation->details;
            $contract->en = $postulation->en;

            if ($coupon) {

              $checkccontracts = CurrentContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();
              $checkfcontracts = FinishedContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();

              if ($coupon->limit > 0) {
                if(!isset($checkccontracts) && !isset($checkccontracts)) {

                  $fee = ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee);
                  $discount = (($fee*(($coupon->percentage = null ? 0 : $coupon->percentage)/100))+($coupon->amount = null ? 0 : $coupon->amount));

                  $contract->coupon_id = $coupon->id;
                  $chargeData = array(
                    'source_id' => $card->token,
                    'method' => 'card',
                    'amount' => ((($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee)*(1 - (($coupon->percentage = null ? 0 : $coupon->percentage)/100)))-($coupon->amount = null ? 0 : $coupon->amount)),
                    'description' => ('Contrato del usuario: ' . $user->name . ' del servicio ' . $category->name . ' realizado por el proveedor: ' . $supplier->company_name),
                    'device_session_id' => $request->device_id,
                    'cvv2' => $request->code
                  );
                }
              }
            } else {

              $fee = ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee);
              $discount = 0;

              $contract->coupon_id = null;
              $chargeData = array(
                'source_id' => $card->token,
                'method' => 'card',
                'amount' => ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee),
                'description' => ('Contrato del usuario: ' . $user->name . ' del servicio ' . $category->name . ' realizado por el proveedor: ' . $supplier->company_name),
                'device_session_id' => $request->device_id,
                'cvv2' => $request->code
              );
            }


            if (!empty($request->card_id) && !empty($request->device_id) && !empty($request->code) && $fee > $discount) {
              try {
                $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));

                $customer = $openpay->customers->get($user->openpay_id);
                $charge = $customer->charges->create($chargeData);


              } 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()
                ]);
              }

              $contract->transaction_id = $charge->id;

            } else if ($coupon) {
              if ($coupon->limit > 0 && $discount >= $fee) {
                if(!isset($checkccontracts) && !isset($checkccontracts)) {
                  $coupon->limit = $coupon->limit - 1;
                  $coupon->save();

                  $contract->transaction_id = $coupon->name;
                }
              }
            }

            $contract->status_id = 1;
            $contract->code = mt_rand(100000, 999999);
            $contract->save();

            $delay_UTC = Carbon::parse($contract->appointment)->subMinutes(30)->toString();

            Postulations::destroy($request->postulation_id);

            OneSignal::sendNotificationUsingTags(
                 "Dirígete a la sección de postulaciones contratadas en la app para ver más detalles",
                 array(
                     ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $supplier->user_id]
                 ),
                 $url = null,
                 $data = null,
                 $buttons = null,
                 $schedule = null,
                 $headings = "Proveedor: has sido contratado"
            );

            //Schedule a notification for the supplier about its appointment
            OneSignal::sendNotificationUsingTags(
                 "Tienes un servicio en " . $contract->address . " hoy en 30 minutos. Dírigeta a la sección de postulaciones contratados para más detalles",
                 array(
                     ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $supplier->user_id]
                 ),
                 $url = null,
                 $data = null,
                 $buttons = null,
                 $schedule = $delay_UTC,
                 $headings = "Proveedor, no olvides tu cita de hoy"
            );

            //Schedule a notification for the user about its appointment
            OneSignal::sendNotificationUsingTags(
                 "Tienes un servicio agendado hoy en " . $contract->address . " en 30 minutos. Dírigeta a la sección de contratos confirmados para más detalles",
                 array(
                     ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $user->id]
                 ),
                 $url = null,
                 $data = null,
                 $buttons = null,
                 $schedule = $delay_UTC,
                 $headings = $user->name . ", no olvides tu cita de hoy"
            );

            return response()->json([
                'message' => 'Servicio contratado exitosamente'
            ]);
          }
        }
      }
    }

    public function coupon(Request $request) {

      $rules = [
        'postulation_id' => 'required|numeric',
        'supplier_id' => 'required|numeric',
        'coupon' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
      ];

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

        $user = Auth::user();
        $postulation = Postulations::where('id', $request->postulation_id)->first();
        $coupon = Coupon::where('name', $request->coupon)->first();

        if($coupon) {

          if ($user->id == $postulation->user_id) {

            $supplier = Suppliers::where('id', $request->supplier_id)->first();

            $IVA = iChambaParameter::where('id', $supplier->IVA_id)->first();
            $ISR = iChambaParameter::where('id', $supplier->ISR_id)->first();

            $ichambafee =  iChambaParameter::where('parameter', 'ichamba_fee')->first();
            $category = Categories::where('id', $postulation->category_id)->first();
            $checkccontracts = CurrentContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();
            $checkfcontracts = FinishedContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();

            if (!isset($checkccontracts) && !isset($checkccontracts)) {
              if($coupon->percentage == 100) {
                if($coupon->limit > 0) {

                  $contract = new CurrentContracts();
                  $contract->user_id = $postulation->user_id;
                  $contract->supplier_id = $supplier->id;
                  $contract->category_id = $postulation->category_id;
                  $contract->address = $postulation->address;
                  $contract->location = $postulation->location;
                  if (isset($postulation->int_number)) {
                    $contract->int_number = $postulation->int_number;
                  } else {
                    $contract->int_number = 0;
                  }
                  $contract->references = $postulation->references;
                  $contract->appointment = $postulation->appointment;
                  $contract->amount = ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee);
                  if (isset($IVA->num_value) && isset($IVA->num_value)) {
                    $contract->IVA = $IVA->num_value;
                    $contract->ISR = $ISR->num_value;
                    $contract->revenue = ((($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee) * ((100 - $ichambafee->num_value) / 100)) * ((100 - $IVA->num_value - $ISR->num_value) / 100));
                  } else {
                    $contract->IVA = 0;
                    $contract->ISR = 0;
                    $contract->revenue = (($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee) * ((100 - $ichambafee->num_value) / 100));
                  }
                  $contract->ichamba_fee = $ichambafee->num_value;
                  $contract->details = $postulation->details;
                  $contract->en = $postulation->en;
                  $contract->coupon_id = $coupon->id;
                  $contract->transaction_id = $coupon->name;
                  $contract->status_id = 1;
                  $contract->code = mt_rand(100000, 999999);
                  $contract->save();

                  $delay_UTC = Carbon::parse($contract->appointment)->subMinutes(30)->toString();

                  Postulations::destroy($request->postulation_id);

                  OneSignal::sendNotificationUsingTags(
                       "Dirígete a la sección de postulaciones contratadas en la app para ver más detalles",
                       array(
                           ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $supplier->user_id]
                       ),
                       $url = null,
                       $data = null,
                       $buttons = null,
                       $schedule = null,
                       $headings = "Proveedor: has sido contratado"
                  );

                  //Schedule a notification for the supplier about its appointment
                  OneSignal::sendNotificationUsingTags(
                       "Tienes un servicio en " . $contract->address . " hoy en 30 minutos. Dírigeta a la sección de postulaciones contratados para más detalles",
                       array(
                           ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $supplier->user_id]
                       ),
                       $url = null,
                       $data = null,
                       $buttons = null,
                       $schedule = $delay_UTC,
                       $headings = "Proveedor, no olvides tu cita de hoy"
                  );

                  //Schedule a notification for the user about its appointment
                  OneSignal::sendNotificationUsingTags(
                       "Tienes un servicio agendado hoy en " . $contract->address . " en 30 minutos. Dírigeta a la sección de contratos confirmados para más detalles",
                       array(
                           ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $user->id]
                       ),
                       $url = null,
                       $data = null,
                       $buttons = null,
                       $schedule = $delay_UTC,
                       $headings = $user->name . ", no olvides tu cita de hoy"
                  );

                  $coupon->limit = $coupon->limit - 1;
                  $coupon->save();

                  return response()->json([
                      'name' => 'success'
                  ]);
              //
                } else {
                  return response()->json([
                      'name' => 'expired'
                  ]);
                }
              } else {
                return response()->json($coupon);
              }
            } else {
              return response()->json([
                  'name' => 'used'
              ]);
            }
          }
        }
      }
    }

    public function couponextra(Request $request) {

      $rules = [
        'contract_id' => 'required|numeric',
        'amount' => 'required|numeric',
        'coupon' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
      ];

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

        $user = Auth::user();
        $fcontract = FinishedContracts::where('id', $request->contract_id)->first();

        $supplier = Suppliers::where('id', $fcontract->supplier_id)->first();
        $IVA = iChambaParameter::where('id', $supplier->IVA_id)->first();
        $ISR = iChambaParameter::where('id', $supplier->ISR_id)->first();
        $ichambafee =  iChambaParameter::where('parameter', 'ichamba_fee')->first();

        $coupon = Coupon::where('name', $request->coupon)->first();

        if($coupon) {

          if ($user->id == $fcontract->user_id) {

            $checkccontracts = CurrentContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();
            $checkfcontracts = FinishedContracts::where('coupon_id', $coupon->id)->where('user_id', $user->id)->first();

            if (!isset($checkccontracts) && !isset($checkccontracts)) {
              if($coupon->percentage == 100) {
                if($coupon->limit > 0) {

                  $extra = new FinishedContracts();
                  $extra->user_id = $fcontract->user_id;
                  $extra->supplier_id = $fcontract->supplier_id;
                  $extra->category_id = $fcontract->category_id;
                  $extra->address = $fcontract->address;
                  $extra->location = $fcontract->location;
                  $extra->int_number = $fcontract->int_number;
                  $extra->references = $fcontract->references;
                  $extra->appointment = Carbon::now();
                  $extra->amount = ($request->amount < 150 ? 150 : $request->amount);
                  if (isset($IVA->num_value) && isset($IVA->num_value)) {
                    $extra->IVA = $IVA->num_value;
                    $extra->ISR = $ISR->num_value;
                    $extra->revenue = ((($request->amount < 150 ? 150 : $request->amount) * ((100 - $ichambafee->num_value) / 100)) * ((100 - $IVA->num_value - $ISR->num_value) / 100));
                  } else {
                    $extra->IVA = 0;
                    $extra->ISR = 0;
                    $extra->revenue = (($request->amount < 150 ? 150 : $request->amount) * ((100 - $ichambafee->num_value) / 100));
                  }
                  $extra->ichamba_fee = $ichambafee->num_value;
                  $extra->en = $fcontract->en;
                  $extra->coupon_id = $coupon->id;
                  $extra->transaction_id = $coupon->name;
                  $extra->status_id = 3;
                  $extra->parent_contract_id = $fcontract->id;
                  $extra->save();

                  $coupon->limit = $coupon->limit - 1;
                  $coupon->save();

                  return response()->json([
                      'name' => 'success'
                  ]);
                } else {
                    return response()->json([
                        'name' => 'expired'
                    ]);
                  }
              } else {
                  return response()->json($coupon);
                }
            } else {
                return response()->json([
                    'name' => 'used'
                ]);
              }
          }
        }
      }
    }

    public function getcurrentcontracts(Request $request) {
      $user = Auth::user();
      $ccontracts = CurrentContracts::where('user_id', $user->id)->orderBy('created_at', 'DESC')->get();
      $currentcontracts  = array();

        foreach($ccontracts as $ccontract) {
          $category = Categories::where('id', $ccontract->category_id)->first();
          $supplier = Suppliers::where('id', $ccontract->supplier_id)->first();
          $time_limit = Carbon::parse($ccontract->appointment);
          $day_limit = Carbon::parse($ccontract->created_at);
          $currentcontractinfo = array(
            'id' => $ccontract->id,
            'phone' => $supplier->user->phone,
            'category' => $category->name,
            'en_category' => $category->en_name,
            'address' => $ccontract->address,
            'date' => $ccontract->appointment,
            'supplier' => $supplier->company_name,
            'status' => $ccontract->status_id,
            'amount' => $ccontract->amount,
            'code' => $ccontract->code,
            'rescheadulable' => $day_limit->diffInDays($time_limit),
            'time_limit' => $time_limit->diffInMinutes(Carbon::now()),
            'past_due' => $time_limit->diffInHours(Carbon::now(), false)
          );
          $currentcontracts[] = $currentcontractinfo;
        }

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

    public function cancelcontract(Request $request) {

      $rules = [
        'contract_id' => 'required|numeric',
      ];

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

        $user = Auth::user();
        $ccontract = CurrentContracts::where('id', $request->contract_id)->first();
        $supplier = Suppliers::where('id', $ccontract->supplier_id)->first();

        if ($user->id == $ccontract->user_id) {

          $time_limit = Carbon::parse($ccontract->appointment);
          if ($time_limit->diffInHours(Carbon::now()) >= 24) {
            if($ccontract->transaction_id != 'NO APPLY') {
              try {
                $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));

                $refundData = array(
                  'description' => 'Reembolso del contrato con id: ' . $ccontract->id . ', del usuario ' . $user->name . '. Con proveedor: ' . $supplier->id,
                );

                $customer = $openpay->customers->get($user->openpay_id);
                $charge = $customer->charges->get($ccontract->transaction_id);
                $charge->refund($refundData);
              } 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()
                ]);
              }
            }
          }

          $fcontract = new FinishedContracts();
          $fcontract->user_id = $ccontract->user_id;
          $fcontract->supplier_id = $ccontract->supplier_id;
          $fcontract->category_id = $ccontract->category_id;
          $fcontract->address = $ccontract->address;
          $fcontract->location = $ccontract->location;
          $fcontract->int_number = $ccontract->int_number;
          $fcontract->references = $ccontract->references;
          $fcontract->appointment = $ccontract->appointment;
          $fcontract->amount = $ccontract->amount;
          $fcontract->IVA = $ccontract->IVA;
          $fcontract->ISR = $ccontract->ISR;
          $fcontract->ichamba_fee = $ccontract->ichamba_fee;
          $fcontract->revenue = $ccontract->revenue;
          $fcontract->details = $ccontract->details;
          $fcontract->en = $ccontract->en;
          $fcontract->transaction_id = (!empty($charge->id) ? $charge->id : $ccontract->transaction_id);
          $fcontract->status_id = 4;
          $fcontract->save();

          CurrentContracts::destroy($request->contract_id);

            OneSignal::sendNotificationUsingTags(
               "El servicio en " . $fcontract->address . " el día " . substr($fcontract->appointment, 0, 10) . "ha sido cancelado. Dírigeta a la sección de servicios contratados para más detalles",
               array(
                   ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $supplier->user_id]
               ),
               $url = null,
               $data = null,
               $buttons = null,
               $schedule = null,
               $headings = "Proveedor: un servicio ha sido cancelado"
            );

          return response()->json([
              'message' => 'Servicio cancelado exitosamente'
          ]);
        }
      }
    }

    public function startcontract(Request $request) {

      $rules = [
        'contract_pin' => 'required|numeric',
      ];

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

        $user = Auth::user();
        $supplier = $user->suppliers;
        $ccontract = CurrentContracts::where('code', $request->contract_pin)->where('supplier_id', $supplier->id)->first();

        if($ccontract) {

          $time_limit = Carbon::parse($ccontract->appointment);
          if ($time_limit->diffInMinutes(Carbon::now()) <= 120) {
            $fcontract = new FinishedContracts();
            $fcontract->user_id = $ccontract->user_id;
            $fcontract->supplier_id = $ccontract->supplier_id;
            $fcontract->category_id = $ccontract->category_id;
            $fcontract->address = $ccontract->address;
            $fcontract->location = $ccontract->location;
            $fcontract->int_number = $ccontract->int_number;
            $fcontract->references = $ccontract->references;
            $fcontract->appointment = $ccontract->appointment;
            $fcontract->amount = $ccontract->amount;
            $fcontract->IVA = $ccontract->IVA;
            $fcontract->ISR = $ccontract->ISR;
            $fcontract->ichamba_fee = $ccontract->ichamba_fee;
            $fcontract->revenue = $ccontract->revenue;
            $fcontract->details = $ccontract->details;
            $fcontract->en = $ccontract->en;
            $fcontract->coupon_id = $ccontract->coupon_id;
            $fcontract->transaction_id = $ccontract->transaction_id;
            $fcontract->status_id = 3;
            $fcontract->score = 5;
            $fcontract->save();

            $supplier->total_score = ($supplier->total_score + 5);
            $supplier->finished_jobs = ($supplier->finished_jobs + 1);
            $supplier->save();

            CurrentContracts::destroy($ccontract->id);

            $payment = new Payments();
            $payment->contract_id = $fcontract->id;
            $payment->supplier_id = $fcontract->supplier_id;
            $payment->amount = $fcontract->amount;
            $payment->status_id = null;
            $payment->save();

              OneSignal::sendNotificationUsingTags(
                 "El servicio en " . $fcontract->address . " el día " . substr($fcontract->appointment, 0, 10) . " ha sido iniciado. Dírigeta a la sección de servicios contratados para más detalles",
                 array(
                     ["field" => "tag", "key" => "iChamba_ID", "relation" => "=", "value" => $fcontract->user_id]
                 ),
                 $url = null,
                 $data = null,
                 $buttons = null,
                 $schedule = null,
                 $headings = "Usuario: el proveedor ha iniciado el servicio"
              );

            return response()->json([
                'message' => 'Servicio iniciado exitosamente'
            ]);
          } else {
            return response()->json([
                'message' => 'No service'
            ]);
          }
        } else {
          return response()->json([
              'message' => 'No service'
          ]);
        }
      }
    }

    public function extra(Request $request) {

      $rules = [
        'contract_id' => 'required|numeric',
        'amount' => 'required|numeric',
        'card_id' => 'required|numeric',
        'code' => 'required|numeric',
        'device_id' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
        'coupon' => 'nullable|string|regex:/(^[A-Za-z0-9 ]+$)+/',
      ];

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

      $user = Auth::user();
      $coupon = Coupon::where('name', $request->coupon)->first();
      $fcontract = FinishedContracts::where('id', $request->contract_id)->first();
      Openpay::setProductionMode(true);

        if ($user->id == $fcontract->user_id) {
          $card = Cards::where('id', $request->card_id)->first();
          $IVA = iChambaParameter::where('id', $supplier->IVA_id)->first();
          $ISR = iChambaParameter::where('id', $supplier->ISR_id)->first();
          $ichambafee =  iChambaParameter::where('parameter', 'ichamba_add_fee')->first();
          $supplier = Suppliers::where('id', $fcontract->supplier_id)->first();

          if ($card->user_id == $user->id) {
            $openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
          }

          $extra = new FinishedContracts();
          $extra->user_id = $fcontract->user_id;
          $extra->supplier_id = $fcontract->supplier_id;
          $extra->category_id = $fcontract->category_id;
          $extra->address = $fcontract->address;
          $extra->location = $fcontract->location;
          $extra->int_number = $fcontract->int_number;
          $extra->references = $fcontract->references;
          $extra->appointment = Carbon::now();
          $extra->amount = ($request->amount < 150 ? 150 : $request->amount);
          if (isset($IVA->num_value) && isset($IVA->num_value)) {
            $extra->IVA = $IVA->num_value;
            $extra->ISR = $ISR->num_value;
            $extra->revenue = ((($request->amount < 150 ? 150 : $request->amount) * ((100 - $ichambafee->num_value) / 100)) * ((100 - $IVA->num_value - $ISR->num_value) / 100));
          } else {
            $extra->IVA = 0;
            $extra->ISR = 0;
            $extra->revenue = (($request->amount < 150 ? 150 : $request->amount) * ((100 - $ichambafee->num_value) / 100));
          }
          $extra->ichamba_fee = $ichambafee->num_value;
          $extra->en = $fcontract->en;

          if ($coupon) {
            if ($coupon->limit > 0) {
              $extra->coupon_id = $coupon->id;
              $chargeData = array(
                'source_id' => $card->token,
                'method' => 'card',
                'amount' => ((($request->amount < 150 ? 150 : $request->amount)*(1 - (($coupon->percentage = null ? 0 : $coupon->percentage)/100)))-($coupon->amount = null ? 0 : $coupon->amount)),
                'description' => ('Contrato del usuario: ' . $user->name . ' del servicio ' . $category->name . ' realizado por el proveedor: ' . $supplier->company_name),
                'device_session_id' => $request->device_id,
                'cvv2' => $request->code
              );
            } else {
              $extra->coupon_id = null;
              $chargeData = array(
                'source_id' => $card->token,
                'method' => 'card',
                'amount' => ($request->amount < 150 ? 150 : $request->amount),
                'description' => ('Contrato del usuario: ' . $user->name . ' del servicio ' . $category->name . ' realizado por el proveedor: ' . $supplier->company_name),
                'device_session_id' => $request->device_id,
                'cvv2' => $request->code
              );
            }
          } else {
            $extra->coupon_id = null;
            $chargeData = array(
              'source_id' => $card->token,
              'method' => 'card',
              'amount' => ($request->amount < 150 ? 150 : $request->amount),
              'description' => ('Contrato del usuario: ' . $user->name . ' del servicio ' . $category->name . ' realizado por el proveedor: ' . $supplier->company_name),
              'device_session_id' => $request->device_id,
              'cvv2' => $request->code
            );
          }

          $customer = $openpay->customers->get($user->openpay_id);
          $charge = $customer->charges->create($chargeData);

          $extra->transaction_id = $charge->id;
          $extra->status_id = 3;
          $extra->parent_contract_id = $fcontract->id;
          $extra->save();

          if ($coupon) {
            $coupon->limit = $coupon->limit - 1;
            $coupon->save();
          }

          return response()->json([
              'message' => 'extra_added'
          ]);

        }
      }

    }

    public function getfinishedcontracts(Request $request) {
      $user = Auth::user();
      $fcontracts = FinishedContracts::where('user_id', $user->id)->orderBy('created_at', 'DESC')->get();
      $finishedcontracts  = array();

        foreach($fcontracts as $fcontract) {
          $category = Categories::where('id', $fcontract->category_id)->first();
          $supplier = Suppliers::where('id', $fcontract->supplier_id)->first();
          $time_limit = Carbon::parse($fcontract->appointment);
          $day_limit = Carbon::parse($fcontract->created_at);
          $finishedcontractinfo = array(
            'id' => $fcontract->id,
            'category' => $category->name,
            'en_category' => $category->en_name,
            'address' => $fcontract->address,
            'date' => $fcontract->appointment,
            'date_difference' => $time_limit->diff(Carbon::now(), false)->days,
            'supplier' => $supplier->company_name,
            'amount' => $fcontract->amount,
            'scored' => $fcontract->scored_at,
            'parent' => $fcontract->parent_contract_id,
            'status' => $fcontract->status->name
          );
          $finishedcontracts[] = $finishedcontractinfo;
        }

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

    public function reviewcontract(Request $request) {

      $rules = [
        'contract_id' => 'required|numeric',
        'rate' => 'required|numeric',
        'comment' => 'string',
      ];

      $validator = Validator::make($request->all(), $rules);
      if ($validator->fails()) {
        return redirect()->back()->withInput($request->all())->withErrors($validator);
      } else {
          $user = Auth::user();
          $fcontract = FinishedContracts::where('id', $request->contract_id)->first();

          if ($fcontract->user_id == $user->id) {
            $fcontract->score = $fcontract->score - (5 - $request->rate);
            $fcontract->scored_at = Carbon::now();
            $fcontract->comments = strip_tags($request->comment);
            $fcontract->save();

            $supplier = Suppliers::where('id', $fcontract->supplier_id)->first();
            $supplier->total_score = $supplier->total_score - (5 - $request->rate);
            $supplier->save();
          }
      }
      return response()->json([
          'message' => 'Calificación registrada con éxito, muchas gracias'
      ]);
    }

    public function deletemissed()
    {
      $contracts = CurrentContracts::whereDate('appointment', '<', Carbon::now())->delete();
    }

    public function currentdestroy($id)
    {
      CurrentContracts::destroy($id);
      return redirect('currentcontracts');
    }

    public function finisheddestroy($id)
    {
      FinishedContracts::destroy($id);
      return redirect('finishedcontracts');
    }
}
