<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Packages;
use App\Facilities;
use App\Excesses;
use Session;
use App\Repository\PackagesRepository;
use App\Transactions;
use App\Addresses;
use App\Customers;
use App\GocardlessCustomers;
use App\GocardlessSubscriptions;
use Stripe;
use Carbon\Carbon;
use DB;
use App\PackageFacilities;
use App\SubscriptionFacilities;
use DateTime;
use Date;
use App\Helpers\PasswordEncryptHelper;
use App\Categories;
// use App\GocardlessSubscription;
use Illuminate\Support\Facades\Auth;
use App\EmailsResponders;
use App\Helpers\Functions;
use App\Helpers\EmailTemplates;
use PDF;
use Mail;
use Illuminate\Support\Str;

class CheckoutController extends Controller {

    private $packages;
    protected $facilities;
    protected $key;
    protected $slug;
    protected $gocardless;

    public function __construct(PackagesRepository $packages) {
        $this->packages = $packages;
        $this->key = env('HUBSPOT_API_KEY');

        $access_token = getenv('GOCARDLESS_TOKEN');
        $this->gocardless = new \GoCardlessPro\Client(array(
            'access_token' => $access_token,
            'environment' => getenv('GOCARDLESS_ENV')
        ));
    }

    public function index() {


        $data = array();
        $id = Session::get('package');
        $type = Session::get('type');
        $excess_id = Session::get('excess_id');


        if (empty($id)) {
            return redirect("/");
            die("sss");
        }

        $model = Packages::where("id", $id)->first();
        $package = $this->packages->setPackage($model);
        //d($package,1);

        $this->packages = $package;

        $facilities = array();

        $selectedFacilities = array();
        if (Session::has('facilities')) {
            $selectedFacilities = Session::get('facilities');
        }

        if (count($package["facilities"]) > 0) {
            $facilities = Facilities::
                    join('package_facilities', 'package_facilities.facility_id', '=', 'facilities.id')
                    ->where("package_facilities.package_id", $id)
                    ->where("status", 1)
                    ->get();
        }

        $excess = Excesses::find($excess_id);

        $prices = $package['prices'][$type][$excess_id];

        $data["package"] = $package;
        $total = 0;
        $price = 0;
        $vat = 0;
        if (!empty($selectedFacilities)) {
            $facilitiesPrices = PackageFacilities::where("package_facilities.package_id", $model->id)->whereIn("package_facilities.facility_id", $selectedFacilities)->get();

            foreach ($facilitiesPrices as $p) {
                $total = $total + $p->price;
                $v = $p->price * ($prices["vat"] / 100);
                $price += ($p->price - $v);
                $vat += $v;
            }


            $prices["price"] = $prices["price"] + $price;
            $prices["total_price"] = $prices["total_price"] + $total;
            $prices["vat_amount"] = $prices["total_price"] - $prices["price"];
        } else {
            $prices["vat_amount"] = $prices["total_price"] - $prices["price"];
        }

        Session::put('prices', $prices);

        $data["prices"] = $prices;
        $data["selectedFacilities"] = $selectedFacilities;
        $data["facilities"] = $facilities;
        $data["excess"] = $excess;
        $data["type"] = $type;
        $data["excess_id"] = $excess_id;
        $data["packagesType"] = Config("params.packages_types." . $type);

        $data["categories"] = Categories::where("status", 1)->get();
        if (!empty(auth('customers')->user())) {
            $data['title'] = auth('customers')->user()->title;
            $data['customer_id'] = auth('customers')->user()->id;
            $data['firstName'] = auth('customers')->user()->firstName;
            $data['lastName'] = auth('customers')->user()->lastName;
            $data['emailAddress'] = auth('customers')->user()->email;
            $data['phone'] = auth('customers')->user()->phone;
            $address = Addresses::where("customer_id", $data['customer_id'])->latest()->first();
            $data['customerAddress'] = $address->address1;
            $data['customerAddress1'] = $address->address2;
            $data['city'] = $address->city;
            $data['postcode'] = $address->postcode;
        } else {
            $response['url'] = url("checkout");
        }


        return view('front/checkout', $data);
    }

    public function validatestep1(Request $request) {

        //required|unique:cun|max:255
        $rules = [
            'title' => 'required',
            'first_name' => 'required',
            'last_name' => 'required',
            'phone' => 'required|size:11',
            'password' => 'required|min:6|confirmed',
        ];

        if (empty(auth('customers')->user())) {
            $rules["email"] = 'email|required|unique:customers|max:255';
        } else {
            $rules["email"] = 'required|email|unique:customers,email,' . auth('customers')->user()->id;
        }

        $messages = [
            'first_name.required' => 'Please enter your First Name!',
            'last_name.required' => 'Please enter your Last Name!',
            'phone.required' => 'Please enter your Phone Number!',
            'email.required' => 'Please enter an email address as this will be used to create your online account.',
            'phone.size' => 'Your phone number needs to be 11 digits long',
            'password.required' => 'Please enter a unique password so that your account can be created',
            'password.min' => 'Your password needs to be a minimum of 6 characters.',
            'password.confirmed' => 'Password and Confirm Password field shoud match!',
        ];

        $input = $request->all();

        $validator = Validator::make($input, $rules, $messages);
        $header = 200;
        $response = array();
        $response['errors'] = array();
        $response['error'] = false;

        if ($validator->fails()) {
            $errors = $validator->errors();
            $response['errors'] = $errors;
            $response['error'] = true;
            $header = 402;
            //return redirect()->back()->withErrors($validator->errors())->withInput();
        } else {
            Session::put('first_name', $input["first_name"]);
            Session::put('last_name', $input["last_name"]);
            Session::put('email', $input["email"]);
            Session::put('password', $input["password"]);
            Session::put('customerType', $input["customerType"]);
            Session::put('phone', $input["phone"]);
            Session::put('title', $input["title"]);

            $response["customerType"] = Session::get('customerType');
            $response["title"] = Session::get('title');
            $response["first_name"] = Session::get('first_name');
            $response["last_name"] = Session::get('last_name');
            $response["phone"] = Session::get('phone');
            $response["email"] = Session::get('email');
            $response["password"] = Session::get('password');
        }



        return response()->json($response, $header);
    }

    public function validatestep2(Request $request) {


        //required|unique:cun|max:255
//        $afterDate= date('Y-m-d', strtotime($new_date_format. ' + 9 days'));
        $customer = Customers::find(1);

        $afterDate = date("d-m-Y", strtotime("- 1 days"));

        $input = $request->all();

        // $input['age'] = (int) $input['age'];


        $rules = [
            'address' => 'required',
            'postcode' => 'required',
            'age' => 'required|min:1',
            'date' => 'date_format:d-m-Y|after:' . $afterDate,
        ];

        $messages = [
            'address.required' => 'Please Enter Your Address',
            'postcode.required' => 'Please Enter Your Postcode',
            'age.required' => 'Please Enter How Many Years Old Is Your Boiler?',
            'age.min' => 'Boiler Age must be greater than 0',
            'date.required' => 'We need to know agreement start date!'
        ];


        $validator = Validator::make($input, $rules, $messages);


        $header = 200;
        $response = array();
        $response['errors'] = array();
        $response['error'] = false;
        if ($validator->fails()) {
            $errors = $validator->errors();
            $response['errors'] = $errors;
            $response['error'] = true;

            // d($response['errors'],1);
            // $header = 402;
            //return redirect()->back()->withErrors($validator->errors())->withInput();
        } else {

            $date = new DateTime($input['date']);
            $new_date_format = $date->format('Y-m-d');
            Session::put('address1', $input["address"]);
            Session::put('address2', $input["address2"]);
            Session::put('postcode', $input["postcode"]);
            Session::put('city', $input["city"]);
            Session::put('date', $new_date_format);
            Session::put('boilerAge', $input["age"]);


            $response["address1"] = Session::get('address1');
            $response["address2"] = Session::get('address2');
            $response["postcode"] = Session::get('postcode');
            $response["date"] = Session::get('date');
            $response["boilerAge"] = Session::get('boilerAge');
            $response["city"] = Session::get('city');
        }

        return response()->json($response, $header);
    }

    public function finalcheckout(Request $request) {

         d($request->all(),1);

        \Stripe\Stripe::setApiKey(env("STRIPE_SECRET"));

        $input = $request->all();
        $input["customerType"] = Session::get('customerType');
        $input["title"] = Session::get('title');
        $input["first_name"] = Session::get('first_name');
        $input["last_name"] = Session::get('last_name');
        $input["phone"] = Session::get('phone');
        $input["email"] = Session::get('email');
        $input["password"] = Session::get('password');
        $input["address"] = Session::get('address1');
        $input["address2"] = Session::get('address2');
        $input["postcode"] = Session::get('postcode');
        $input["date"] = Session::get('date');
        $input["boilerAge"] = Session::get('boilerAge');
        $input["city"] = Session::get('city');
        $input["created_at"] = date("Y-m-d H:i:s");

        $agreementDate = Session::get('date');


        $rules = [
            'customerType' => 'required',
            'title' => 'required',
            'first_name' => 'required',
            'last_name' => 'required',
            'phone' => 'required|size:11',
            'email' => 'email|required',
            "payment_method" => "required",
            "terms" => "required",
            'address' => 'required',
            'postcode' => 'required',
            'boilerAge' => 'required',
            'date' => 'required',
            'terms' => 'required',
        ];

        $messages = [
            'first_name.required' => 'We need to know your First Name!',
            'last_name.required' => 'We need to know your Last Name!',
            'phone.required' => 'We need to know your phone!',
            'email.required' => 'We need to know your email address!',
            'address.required' => 'We need to know your address!',
            'postcode.required' => 'We need to know your postcode!',
            'boilerAge.required' => 'We need to know your boiler age!',
            'date.required' => 'We need to know agreement start date!',
            'payment_method.required' => 'Please choose payment method',
            'terms.required' => 'Please accept our terms and conditions',
        ];

        $customer = [
            "title" => $input["title"],
            "type" => $input["customerType"],
            "firstName" => $input["first_name"],
            "lastName" => $input["last_name"],
            "phone" => $input["phone"],
            "email" => $input["email"],
            "password" => bcrypt($input["password"]),
            "created_at" => $input["created_at"]
        ];

        $address = [
            "address1" => $input["address"],
            "address2" => $input["address2"],
            "city" => $input["city"],
            "postcode" => $input["postcode"],
            "created_at" => $input["created_at"]
        ];

        $validator = Validator::make($input, $rules, $messages);
        $header = 200;
        $response = array();
        $response['errors'] = array();
        $response['error'] = false;
        if ($validator->fails()) {
            $errors = $validator->errors();
            $response['errors'] = $errors;
            $response['error'] = true;
            $header = 402;

            //return redirect()->back()->withErrors($validator->errors())->withInput();
        } else {

            $row = Transactions::orderBy("id", "desc")->first();
            $id = isset($row->id) ? $row->id : 0;
            $invoiceNumber = 1000 + ($id + 1);
            $invoiceNumber = "HF" . $invoiceNumber;

            $package_id = Session::get('package');
            $type = Session::get('type');
            $excess_id = Session::get('excess_id');

            $prices = Session::get('prices');

            $model = Packages::where("id", $package_id)->first();
            // $package = $this->packages->setPackage($model);

            $this->slug = Str::kebab($model->title); // e.g ( Mini Flo to mini-flo)
            //$prices = $package['prices'][$type][$excess_id];
            $description = $model->title . " " . ucfirst($type) . " subscription of " . Config("params.currency.symbol") . $prices["total_price"];



            if ($input["payment_method"] == "credit_card") {


                $excess = Excesses::find($excess_id);

                if (empty(auth('customers')->user())) {
                    $response = $this->saveCustomer($customer, $address);
                    $customer_id = $response["customer_id"];
                    Session::put("new_user", "Yes");
                } else {
                    $customer_id = auth('customers')->user()->id ?? 0;
                    $address["customer_id"] = $customer_id;
                    Customers::where("id", $customer_id)->update($customer);
                    Addresses::where("customer_id", $customer_id)->update($address);
                }
                //echo Session::get('new_user');
                //die;




                Session::put('customer_id', $customer_id);
                $user = Customers::find($customer_id);


                $planId = "plan-" . $package_id . "-" . $type . "-" . $excess_id;
                $name = $model->title . ", " . $excess->title . ", " . ucfirst($type);


                $date1 = date_create(date("Y-m-d"));
                $date2 = date_create($input["date"]);

                $diff = date_diff($date1, $date2);
                $days = (int) $diff->format("%R%a");

                $anchorDate = $input["date"];
                $anchorDate2 = date('d/m/Y', strtotime($input["date"]));
                $anchorDate3 = date('d/m/Y', strtotime($input["date"]));


                if ($input["payment_method"] == "credit_card") {
                    $limit = 1;
                } else {
                    $limit = 10;
                }
                //echo $limit;


                if ($days < $limit) {
                    $add = 10 - $days;
                    $anchorDate = date('Y-m-d', strtotime($input["date"] . ' + ' . $add . ' days'));
                    $anchorDate2 = date('d/m/Y', strtotime($input["date"] . ' + ' . $add . ' days'));
                    $anchorDate3 = date('d/m/Y', strtotime($input["date"]));
                }

                Session::put('hub_spot_date', $anchorDate2);



                $anchor = Carbon::createFromFormat('Y-m-d', $anchorDate);

                

                try {
                    $plan = \Stripe\Plan::retrieve($planId);
                } catch (Stripe\Exception\InvalidRequestException $e) {

                    $amount = (INT) ($prices["total_price"] * 100);
                    
                    $plan = \Stripe\Plan::create(array(
                                "amount" => $amount,
                                "interval" => rtrim($type, "ly"),
                                "product" => array("name" => $name),
                                "currency" => "gbp",
                                "id" => $planId
                    ));
                }

                $stripeCustomer = $user->createOrGetStripeCustomer();

                //$anchor = Carbon::createFromFormat('Y-m-d', $input["date"]);
                
                // old code for subscription 11-01-2023
                //$newSubscription = $user->newSubscription('default', $plan->id)->anchorBillingCycleOn($anchor->startOfDay())->create($input["payment_method_id"], [
                $newSubscription = $user->newSubscription('default', $plan->id)->create($input["payment_method_id"], [
                    'email' => $input["email"],
                        ], [
                    'metadata' => ['note' => $description . " of $invoiceNumber", 'Invoice number' => $invoiceNumber],
                ]);

                if (isset($newSubscription->id)) {
                    $subscriptions = [
                        "customer_id" => $customer_id,
                        "subscription_id" => $newSubscription->id,
                        "paymentMethod" => $input["payment_method"],
                        "boilerAge" => $input["boilerAge"],
                        "package_id" => $package_id,
                        "type" => $type,
                        "excess_id" => $excess_id,
                        "price" => $prices["price"],
                        "vat" => $prices["vat"],
                        "total" => $prices["total_price"],
                        "startDate" => $anchorDate,
                        "created_at" => $input["created_at"]
                    ];
                    $subscription_id = $this->insertTranactions($subscriptions);

                    Session::put('subscription_id', $subscription_id);

                    $this->insertSubscriptionFacilities($subscription_id);

                    //$this->sendEmail($user, $invoiceNumber, $package, $subscriptions, $facilities);
                    //$this->sendEmailPassword(Session::get('email'), Session::get('first_name'), $anchorDate3, $package["title"]);


                    Transactions::where("id", $subscription_id)->update(array("confirmed" => 1, "InvoiceNumber" => $invoiceNumber));
                    $response["redirect_url"] = url("order_successful");
                }
            } else {


                Session::put('payment_method', $input["payment_method"]);
                Session::put('boiler_age', $input["boilerAge"]);
                Session::put('start_date', $input["date"]);

                $params = [
                    "description" => $description,
                    "session_token" => "dummy_session_token",
                    "success_redirect_url" => url("checkout/success"),
                    "prefilled_customer" => [
                        "given_name" => $input["first_name"],
                        "family_name" => $input["last_name"],
                        "email" => $input["email"],
                        "address_line1" => $input["address"],
                        "address_line2" => !empty($input["address2"]) ? $input["address2"] : " not mentioned ",
                        "city" => !empty($input["city"]) ? $input["city"] : " not mentioned ",
                        "postal_code" => $input["postcode"],
                        "country_code" => Config("params.country.iso_code")
                    ]
                ];


                $redirectFlow = $this->gocardless->redirectFlows()->create(["params" => $params]);

                //$redirectFlow = gocardless()->redirectFlows()->create(["params" => $params]);
                $response["redirect_flow_id"] = $redirectFlow->id;
                $response["redirect_url"] = $redirectFlow->redirect_url;
                // $response["redirect_url"] = $redirectFlow->redirect_url = 'order_successful';
            }

            //Session::put('subscription_id', $subscription_id);
        }

        return response()->json($response, $header);
    }

    public function saveCustomer($customer, $address) {

        $customer_id = Customers::insertGetId($customer);
        $address["customer_id"] = $customer_id;
        $address_id = Addresses::insertGetId($address);

        auth("customers")->loginUsingId($customer_id, false);
        $user = auth()->guard('customers')->user();
        $tokenResult = $user->createToken(env("APP_NAME"));
        $token = $tokenResult->token;
        $token->save();
        return $response = [
            'customer_id' => $customer_id,
            'error' => false,
            'access_token' => $tokenResult->accessToken,
            'token_type' => 'Bearer',
            'expires_at' => Carbon::parse($tokenResult->token->expires_at)->toDateTimeString()
        ];
    }

    public function insertTranactions($input) {

        return $subscription_id = Transactions::insertGetId($input);
    }

    public function insertSubscriptionFacilities($id) {

        $selectedFacilities = Session::get('facilities');
        $package_id = Session::get('package');


        $facilities = Facilities::
                join('package_facilities', 'package_facilities.facility_id', '=', 'facilities.id')
                ->where("package_facilities.package_id", $package_id)
                ->where("status", 1);



        if (!empty($selectedFacilities)) {
            $facilities = $facilities->whereIn("facilities.id", $selectedFacilities);
        }

        $facilities = $facilities->get();
        //echo count($facilities);


        $j = 0;
        $inputs = array();
        foreach ($facilities as $facility) {

            $inputs[$j]["transaction_id"] = $id;
            $inputs[$j]["facility_id"] = $facility->facility_id;
            $inputs[$j]["title"] = $facility->title;
            $inputs[$j]["price"] = $facility->price;
            $inputs[$j]["created_at"] = date("Y-m-d H:i:s");
            $j++;
        }

        SubscriptionFacilities::insert($inputs);
        //return $subscription_id = Transactions::insertGetId($input);
    }

    public function success(Request $request) {
        $currency = Config("params.currency.code");
        $redirect_flow_id = $request->redirect_flow_id;


        $input["created_at"] = date("Y-m-d H:i:s");
        $input["customerType"] = Session::get('customerType');
        $input["title"] = Session::get('title');
        $input["first_name"] = Session::get('first_name');
        $input["last_name"] = Session::get('last_name');
        $input["phone"] = Session::get('phone');
        $input["email"] = Session::get('email');
        $input["address"] = Session::get('address1');
        $input["address2"] = Session::get('address2');
        $input["postcode"] = Session::get('postcode');
        $input["date"] = Session::get('date');
        $input["boilerAge"] = Session::get('boilerAge');
        $input["city"] = Session::get('city');
        $input["password"] = Session::get('password');
        //d($input);



        $date1 = date_create(date("Y-m-d"));
        $date2 = date_create($input["date"]);
        $diff = date_diff($date1, $date2);
        $days = (int) $diff->format("%R%a");
        $anchorDate3 = date('d/m/Y', strtotime($input["date"]));

        if ($days < 10) {
            $add = 10 - $days;
            $input["date"] = date('Y-m-d', strtotime($input["date"] . ' + ' . $add . ' days'));
        }




        //d($input,1);

        $customer = [
            "title" => $input["title"],
            "type" => $input["customerType"],
            "firstName" => $input["first_name"],
            "lastName" => $input["last_name"],
            "phone" => $input["phone"],
            "email" => $input["email"],
            "created_at" => $input["created_at"],
            "password" => bcrypt($input["password"]),
        ];

        $address = [
            "address1" => $input["address"],
            "address2" => $input["address2"],
            "city" => $input["city"],
            "postcode" => $input["postcode"],
            "created_at" => $input["created_at"]
        ];



        if (empty(auth('customers')->user())) {
            $response = $this->saveCustomer($customer, $address);
            $customer_id = $response["customer_id"];
            Session::put('new_user', "Yes");
        } else {
            $customer_id = auth('customers')->user()->id;
            $address["customer_id"] = $customer_id;
            Customers::where("id", $customer_id)->update($customer);
            Addresses::where("customer_id", $customer_id)->update($address);
            Session::put('new_user', false);
        }


        $package_id = Session::get('package');
        $type = Session::get('type');
        $excess_id = Session::get('excess_id');
        $prices = Session::get('prices');
        $model = Packages::where("id", $package_id)->first();
        $package = $this->packages->setPackage($model);

        $facilities = array();
        if (count($package["facilities"]) > 0) {
            $facilities = Facilities::
                            join('package_facilities', 'package_facilities.facility_id', '=', 'facilities.id')
                            ->where("package_facilities.package_id", $package_id)
                            ->where("status", 1)
                            ->select('title')
                            ->get()->toArray();
        }

        try {

            DB::beginTransaction();

            try {

                $redirectFlow = $this->gocardless->redirectFlows()->complete($redirect_flow_id, ["params" => ["session_token" => "dummy_session_token"]]);

                $mandate = $redirectFlow->links->mandate;
                $linksCustomer = $redirectFlow->links->customer;

                $customerInput = [
                    "response" => json_encode($redirectFlow),
                    "customer_id" => $customer_id,
                    "customer" => $linksCustomer,
                    "mandate" => $mandate,
                    "created_at" => date("Y-m-d H:i:s")
                ];
                $goCustomerId = GocardlessCustomers::insertGetId($customerInput);

                $package_id = Session::get('package');
                $type = Session::get('type');
                $excess_id = Session::get('excess_id');
                $prices = $package['prices'][$type][$excess_id];

                $amount = (INT) ($prices["total_price"] * 100);

                $row = Transactions::orderBy("id", "desc")->first();
                $id = isset($row->id) ? $row->id : 0;
                $invoiceNumber = 1000 + ($id + 1);
                $invoiceNumber = "HF" . $invoiceNumber;

                $startDate = $input["date"];

                $paymentMethod = Session::get('payment_method');
                $boilerAge = $input["boilerAge"];

                $response = $this->gocardless->subscriptions()->create([
                    "params" => [
                        "name" => $package["title"],
                        "amount" => $amount, // 15 GBP in pence
                        "currency" => strtoupper($currency),
                        "interval_unit" => strtolower($type),
                        "start_date" => $startDate,
                        "links" => [
                            "mandate" => $mandate
                        // Mandate ID from the last section
                        ],
                        "metadata" => [
                            "subscription_number" => $invoiceNumber
                        ]
                    ],
                    "headers" => [
                        "Idempotency-Key" => randonString(30)
                    ]
                ]);


                $subscriptionInput = [
                    "response" => json_encode($response),
                    "subscription" => $response->id,
                    "gocardless_customer_id" => $goCustomerId,
                    "created_at" => date("Y-m-d H:i:s")
                ];

                $sid = GocardlessSubscriptions::insertGetId($subscriptionInput);

                $subscriptions = [
                    "customer_id" => $customer_id,
                    "subscription_id" => $sid,
                    "paymentMethod" => $paymentMethod,
                    "boilerAge" => $boilerAge,
                    "package_id" => $package_id,
                    "type" => $type,
                    "excess_id" => $excess_id,
                    "price" => $prices["price"],
                    "vat" => $prices["vat"],
                    "total" => $prices["total_price"],
                    "startDate" => Session::get('date'),
                    "invoiceNumber" => $invoiceNumber,
                    "confirmed" => 1,
                    "created_at" => date("Y-m-d H:i:s")
                ];
                $transaction_id = $this->insertTranactions($subscriptions);
                $this->insertSubscriptionFacilities($transaction_id);

                //$user = Customers::find($customer_id);

                Session::put('subscription_id', $transaction_id);
                Session::put('invoice_number', $invoiceNumber);



                //$this->sendEmail($user, $invoiceNumber, $package, $subscriptions, $facilities);
                //$this->sendEmailPassword(Session::get('email'), Session::get('first_name'), $anchorDate3, $package["title"]);
                //Session::forget('package');
                //Session::forget('type');
                //Session::forget('excess_id');
                DB::commit();
                return redirect("order_successful");
            } catch (\Exception $e) {
                DB::rollback();
                print($e->getMessage());
            }


            //return redirect()->away($redirectFlow->confirmation_url);
        } catch (\GoCardlessPro\Core\Exception\InvalidStateException $e) {
            
        }
    }

    public function login(Request $request) {
        $rules = [
            'email' => 'email|required',
            'password' => 'required'
        ];

        $messages = [
            'email.required' => 'Please enter the email address you used to register your account with us.',
            'password.required' => 'Please enter the password for your account.',
        ];
        $input = $request->all();

        $validator = Validator::make($input, $rules, $messages);
        $header = 200;
        $response = array();
        $response['errors'] = array();
        $response['error'] = false;
        if ($validator->fails()) {

            $errors = $validator->errors();
            $response['errors'] = $errors;
            $response['error'] = true;
            $header = 402;
        } else {

            $credentials["email"] = $request->email;
            $credentials["password"] = $request->password;


            if (Auth::guard('customers')->attempt(['email' => $request->email, 'password' => $request->password])) {

                $user = auth()->guard('customers')->user();

                Session::put('first_name', $user["firstName"]);
                Session::put('last_name', $user["lastName"]);
                Session::put('email', $user["email"]);
                Session::put('customerType', $user["type"]);
                Session::put('phone', $user["phone"]);
                Session::put('title', $user["title"]);

                $response["customerType"] = Session::get('customerType');
                $response["title"] = Session::get('title');
                $response["first_name"] = Session::get('first_name');
                $response["last_name"] = Session::get('last_name');
                $response["phone"] = Session::get('phone');
                $response["email"] = Session::get('email');
            } else {
                $response['errors[']["login"] = "Login failed!";
                $response['error'] = true;
            }
        }

        return response()->json($response, $header);
    }

    public function sendEmail($customer, $invoiceNumber, $package, $subscriptions, $facilities) {

        $prices = Session::get('prices');
        $emailsResponders = EmailsResponders::where('Title', 'User - Invoice')->first();
        $agreementDate = Session::get('date');

        $data["body"] = $emailsResponders->Content;
        $data["title"] = $emailsResponders->Title;
        $data["subject"] = $emailsResponders->Subject;

        $replaces["Title"] = $customer->title;
        $replaces["First_Name"] = $customer->firstName;
        $replaces["Last_Name"] = $customer->lastName;
        $replaces["Phone_Number"] = $customer->phone;
        $replaces["Email"] = $customer->email;
        $replaces['Address1'] = $customer->address->address1 ?? '';
        $replaces['Address2'] = $customer->address->address2 ?? '';
        $replaces['City'] = $customer->address->city ?? '';
        $replaces['Zip'] = $customer->address->postcode ?? '';

        $replaces['Package_Name'] = ucfirst($package['title']) ?? '';
        $replaces["CURRENCY"] = env("CURRENCY_SYMBOL");

        $replaces['Total_Price'] = $prices["total_price"];
        $replaces['NET_Amount'] = $prices["price"];
        $replaces["Plan"] = rtrim($subscriptions["type"], "ly") ?? '';

        $replaces["VAT_Amount"] = $prices["vat_amount"];
        $replaces["Invoice_Number"] = $invoiceNumber;
        $replaces["Created_Date_Time"] = date("d/m/y", strtotime($agreementDate));

        $facilities = array_chunk($facilities, 3);

        $count = count($facilities);

        $replaces["Invoice_Service_Table"] = EmailTemplates::setPackageTemplate($facilities, $count);

        $template = Functions::replaces($data, $replaces);
//        d($replaces ,1);

        $pdf = PDF::loadView('front.pdf.invoice', ['data' => $replaces, 'facilities' => $facilities, 'count' => $count]);

        // file_put_contents("test.pdf", $pdf->output());

        try {
            Mail::send('front.emails.template', ['content' => $template["body"]], function ($m) use ($customer, $template, $pdf ) {
                $m->from(env("MAIL_FROM_ADDRESS"), env("MAIL_FROM_NAME"));
                $m->to($customer->email, "test")->subject("New Invoice");
                $m->attachData($pdf->output(), 'invoice.pdf', ['mime' => 'application/pdf',]);
            });
        } catch (\Throwable $th) {
            // throw $th;
        }
    }

    public function sendEmailPassword($email, $first_name, $startDate, $package) {

        $emailsResponders = EmailsResponders::where('Title', 'User - Signup')->first();

        $data["body"] = $emailsResponders->Content;
        $data["title"] = $emailsResponders->Title;
        $data["subject"] = $emailsResponders->Subject;
        $replaces["Email"] = $email;
        $replaces["First_Name"] = $first_name;
        $replaces["Package_Name"] = $package;
        $replaces["Start_Date"] = date("d/m/Y");
        $replaces["Website_Name"] = \URL::to('/');


        $template = Functions::replaces($data, $replaces);

        $subject = $template['subject'];

        try {

            Mail::send('front.emails.template', ['content' => $template["body"]], function ($m) use ( $email, $first_name, $subject ) {
                $m->from(env("MAIL_FROM_ADDRESS"), env("MAIL_FROM_NAME"));
                $m->to($email, $first_name)->subject($subject);
            });
        } catch (\Throwable $th) {
            // throw $th;
        }
    }

    public function storeContact($post) {

//        d($post['age_of_boiler'],1);
        unset($_POST['_token']);

        $arr = array(
            'properties' => array(
                array(
                    'property' => 'email',
                    'value' => $post['email']
                ),
                array(
                    'property' => 'salutation',
                    'value' => $post['salutation']
                ),
                array(
                    'property' => 'firstname',
                    'value' => $post['firstname']
                ),
                array(
                    'property' => 'lastname',
                    'value' => $post['lastname']
                ),
                array(
                    'property' => 'phone',
                    'value' => $post['phone']
                ),
                array(
                    'property' => 'address',
                    'value' => $post['address']
                ),
                array(
                    'property' => 'zip',
                    'value' => $post['zip']
                ),
                array(
                    'property' => 'city',
                    'value' => $post['city']
                ),
                array(
                    'property' => 'state',
                    'value' => $post['state']
                ),
                array(
                    'property' => 'address_line_two',
                    'value' => $post['address_line_two']
                ),
                array(
                    'property' => 'package',
                    'value' => $post['package']
                ),
                array(
                    'property' => 'package_price',
                    'value' => $post['package_price']
                ),
                array(
                    'property' => 'recurring_amount',
                    'value' => 0
                ),
                array(
                    'property' => 'boiler_service_complete',
                    'value' => false
                ),
                array(
                    'property' => 'age_of_boiler',
                    'value' => $post['age_of_boiler']
                ),
                array(
                    'property' => 'lifecyclestage',
                    'value' => 'customer'
                ),
                array(
                    'property' => 'frequency_of_collection',
                    'value' => $post['frequency_of_collection']
                ),
                array(
                    'property' => 'start_date',
                    'value' => $post['start_date']
                ),
            )
        );

        $contactResponse = $this->setCurlData('https://api.hubapi.com/contacts/v1/contact?hapikey=', $arr);

        if (!$contactResponse['status']) {

            return $contactResponse;
        }

        return ['status' => true];
    }

    public function deal($email) {

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, 'https://api.hubapi.com/contacts/v1/contact/email/' . $email . '/profile?hapikey=' . $this->key);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $res = curl_exec($ch);

        $vid = json_decode($res, true)['vid'] ?? '';

        $arr = array(
            "associations" => [
                "associatedVids" => [
                    $vid
                ]
            ],
            'properties' => array(
                array(
                    "value" => 'click here "http://homefloltd.seo-local.co.uk/home-care/' . $this->slug . '" to check your plan',
                    // "value" =>  '   click here "http://homefloltd.seo-local.co.uk/home-care/half-flo" to check your plan',
                    "name" => "dealname"
                ),
            )
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arr));
        curl_setopt($ch, CURLOPT_URL, 'https://api.hubapi.com/deals/v1/deal?hapikey=' . $this->key);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);

        curl_close($ch);

        $result = json_decode($response, true);

        if (array_key_exists('status', $result)) {
            if ($result['status'] == 'error') {
                return ['status' => false, 'message' => $result['message'] ?? ''];
            }
        }

        return ['status' => true];
    }

    public function assignToList($email) {

        $curl = curl_init();

        $endpoint = 'https://api.hubapi.com/contacts/v1/lists/54/add?hapikey=' . $this->key;

        curl_setopt_array($curl, array(
            CURLOPT_URL => $endpoint,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => '{
                "emails": [
                "' . $email . '"    
              ]
            }',
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        $result = json_decode($response, true);

        if (count($result['updated']) == 0) {
            return ['status' => false, 'message' => 'contact cannot assign'];
        }

        return ['status' => true];
    }

    public function setCurlData($url, $payload) {
        $ch = curl_init();

        $endpoint = $url . $this->key;
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_URL, $endpoint);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);

        curl_close($ch);

        $result = json_decode($response, true);

        if (array_key_exists('status', $result)) {
            if ($result['status'] == 'error') {
                return ['status' => false, 'message' => $result['message'] ?? ''];
            }
        }

        return ['status' => true];
    }

    public function getDataByObj($url) {
        $ch = curl_init();
        $endpoint = $url . $this->key;
        curl_setopt($ch, CURLOPT_URL, $endpoint);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $res = curl_exec($ch);
        return json_decode($res, true);
    }

}
