<?php

namespace App\Http\Controllers;

use App\Company;
use App\CompanyStatus;
use App\Role;
use App\Tools\SmsTools;
use App\Traits\CpanelApi;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class companyApiController extends Controller
{
    use CpanelApi;
    public function register(Request $request)
    {

        /** @noinspection PhpDuplicateArrayKeysInspection */
        $validator = Validator::make(
            $request->all(),
            [
                'name' => 'required|unique:companies',
                'nature_of_business' => 'required',
                //                    'nature_of_business' => ['required',Rule::in($this->business())],
                'mobile_money_number' => 'sometimes|nullable|digits_between:10,20',
                'company_phone_number' => 'sometimes|nullable|digits_between:10,20',
                'business_logo' => 'sometimes|nullable',
                'contact_person' => 'required',
                'register_as' => 'required',
                'business_location' => 'required',
                //                    'reseller_username' => 'required_if:register_as,==,reseller_client|exists:users,username',
                'reseller_username' => Rule::requiredIf(function () use ($request) {
                    return $request->input('register_as') == 'reseller_client';
                }),
                /** Contact person validation */
                'contact_person_id' => 'sometimes|nullable|',
                'contact_person_designation' => 'sometimes|nullable',
                'contact_person_phone' => 'required|unique:companies|digits_between:10,20',
                'contact_person_phone' => 'required|unique:users,phone_number|digits_between:10,20',
                'contact_person_email' => 'required|email|min:6|companies:contact_person_email',
                'contact_person_email' => 'required|email|min:6|unique:users,email',
                'username' => 'required|min:6|unique:users',
            ]
        );


        if ($validator->fails()) {
            return response()->json(['code' => 401, 'msg' => $validator->errors()->all()]);
        }

        if ($request->input('register_as')  == 'reseller_client') {
            $user = User::query()->where('username', $request->input('reseller_username'))->first();

            if (empty($user))
                return response()->json(['code' => 401, 'msg' =>
                ['reseller does not exist']]);

            if (!empty($user) && $user->role_id != 3)
                return response()->json(['code' => 401, 'msg' =>
                ['this is not a valid reseller account']]);
        }


        if (
            !empty($request->input('register_as')) &&
            !in_array($request->input('register_as'), ['reseller', 'reseller_client', 'direct_client'])
        ) {
            return response()->json(['code' => 401, 'msg' =>
            ['register_as as parameter must be either reseller,reseller_client or direct_client']]);
        }



        if (!$this->validate_business($request))
            return response()->json(['code' => 401, 'msg' => 'nature of business must one of the following '
                . str_replace(['[', ']'], '', json_encode($this->business()))]);

        $records = $request->except(['contact_person_id', 'business_logo']);

        $records['nature_of_business'] = empty($request->input('nature_of_business')) ? 'N/A' : $request->input('nature_of_business');
        $records['company_phone_number'] = empty($request->input('company_phone_number')) ? 'N/A' : $request->input('company_phone_number');
        $records['contact_person_phone'] = SmsTools::format_gh_number($request->input('contact_person_phone'));
        $records['date_of_incorporation'] = empty($request->input('date_of_incorporation')) ? 'N/A' : $request->input('date_of_incorporation');
        $records['location_in_other_countries'] = empty($request->input('location_in_other_countries')) ? 'N/A' : $request->input('location_in_other_countries');
        $records['physical_address'] = empty($request->input('business_location')) ? 'N/A' : $request->input('business_location');
        $records['postal_address'] = empty($request->input('postal_address')) ? 'N/A' : $request->input('postal_address');

        $result = $this->generateUserInfo($request);

        $result['created_by'] = $records['register_as'] == 'reseller_client' ? $records['reseller_username'] : 'npontu';

        try {
            DB::beginTransaction();
            $user = User::query()->create($result);

            $records['user_id'] = $user->id;

            $user->credit()->create([
                'username' => $user->username,
                'price' => '0.028',
                'email_price' => '0.00332',
                'credit_alloted' => '0.00',
                'old_bal' => '0',
                'new_bal' => '0.00',
                'credit_used' => '0',
                'credited' => '0'
            ]);  // create the user details for the company or individual
            $output = $this->saveFiles($request); // save files
            $company = Company::query()->create($records);  //create the company
            $company->putToTrialMode($records); //put to trial mode
            $company->update($output); // update company records with the files captured


            $balance = $user->credit->price * 3;
            $user->credit->update(['new_bal' => $balance, 'credited' => $balance]);

            $user->update(['company_id' => $company->id]);    //update user table with company table

            $status = $this->setStatus($company);  //sets the company to approved

            $company->update($status);  //updates the company status to be approved


            $data['email'] = $user->email;
            $data['name'] = $user->full_name;
            $data['c_username'] = $user->username;
            $data['c_password'] = $user->pass;
            $data['url'] = route($result['url']);
            $data['content'] = "Your account for Deywuro has been created with username and password";


            try {

                Mail::send('emails.admin_login', $data, function ($m) use ($data) {
                    $m->from('sms@deywuro.com', 'Deywuro');
                    $m->to($data['email'], $data['name']);
                    $m->subject('Company Registration');
                });
            } catch (\Exception $e) {
                $this->appLog('register-api Error');
            }


            try {

                Mail::send('emails.admin_login', ['company' => $company], function ($m) {
                    $m->from('sms@deywuro.com', 'Deywuro');
                    $m->to('support@npontu.com');
                    $m->subject('New Company Registration');
                });
            } catch (\Exception $ex) {
                $this->appLog('register-api Error');
            }


            //             $msg = "Hello {$company->name},
            // Your account for Deywuro has been created with username and password
            // username : {$company->users->username}
            // password : {$company->users->pass}
            // url : {$data['url']}
            // Thank You,
            // Deywuro";
            $msg = "Hello {$company->name},\n\n" .
                "Your account for Deywuro has been created.\n" .
                "Username: {$company->users->username}\n" .
                "Password: {$company->users->pass}\n" .
                "Registered under: {$company->users->created_by}\n" .
                "URL: {$data['url']}\n\n" .
                "Thank you,\nDeywuro";

            $this->sendSms($msg, $company->users->phone_number);

            DB::commit();
            return  response()->json(['code' => 200, 'msg' => $company, 'status' => 'success']);
        } catch (\Exception $ex) {
            DB::rollBack();
            return  response()->json(['code' => 500, 'msg' => [$ex->getMessage()]]);
        }
    }

    private function generateUserInfo(Request $request)
    {
        $inputs['phone_number'] = SmsTools::format_gh_number($request->input('contact_person_phone'));
        $inputs['full_name'] = $request->input('name');
        $words = explode(" ", trim($request->input('name')));
        $acronym = "";
        foreach ($words as $w) {
            if ($w && isset($w[0]) && !empty($w[0]))
                $acronym .= $w[0];
        }

        $password = substr(hash('sha512', rand()), 0, 6);

        $role_id = in_array($request->input('register_as'), ['reseller_client', 'direct_client']) ? 2 : 3;

        $inputs['username'] = $request->input('username');
        $inputs['organisation'] = $request->input('name');;
        $inputs['email'] = $request->input('contact_person_email');
        $inputs['role_id'] = $role_id;
        $inputs['password'] = bcrypt($password);
        $inputs['website_url'] = !empty($request->input('website_url')) ? $request->input('website_url') : null;
        $inputs['status'] = 'active';
        $inputs['must_change_password'] = true;
        $inputs['location'] = empty($request->input('physical_address')) ? 'N/A' : $request->input('physical_address');
        $inputs['pass'] = $password;

        if ($inputs['role_id'] == 2) {
            $inputs['url']  = 'login';
        } else if ($inputs['role_id'] == 3) {
            $inputs['url']  = 'reseller.login';
        }

        return $inputs;
    }

    private function saveFiles(Request $request)
    {
        $records = array();

        if (!empty($request->input('contact_person_id'))) {

            $img  = $request->input('contact_person_id');   //base64 code
            $name = $request->input('name');
            $_name = $this->convertImage($img, $name, 'contact_person');
            $records['contact_person_id'] = $_name;
        }

        if (!empty($request->input('business_logo'))) {

            $img  = $request->input('business_logo');   //base64 code
            $name = $request->input('name');
            $_name = $this->convertImage($img, $name, 'business_logo');
            $records['business_logo'] = $_name;
        }

        return $records;
    }


    public function convertImage($encoded, $name, $path)
    {
        $img  = $encoded;   //base64 code

        $name = $name . date('h:i:s') . '.jpg';
        $_name = str_replace(' ', '_', $name);
        $img =  str_replace(' ', '+', $img);

        /*** End of Base64 Conversion ***/
        $img = base64_decode($img);
        File::put(storage_path() . '/app/public/' . $path . '/' . $_name, $img);
        return $_name;
    }


    private function setStatus($company, $_status = 1)
    {

        $status['company_id'] = $company->id;
        $status['r_code'] = $this->returnCode(4);
        $status['status'] = $_status;
        $save = CompanyStatus::query()->create($status);
        //create a new array and send results
        $expose['company_status_id'] = $save->id;
        $expose['code'] = $status['r_code'];

        return $expose;
    }

    private function returnCode($length)
    {
        $t = Carbon::parse(now())->format('s');
        $random = substr(str_shuffle(str_repeat($x = '0123456789', ceil($length / strlen($x)))), 1, $length);
        return 'DY' . $random . $t;
    }

    public function validate_business(Request $request)
    {
        return in_array($request->input('nature_of_business'), $this->business());
    }

    public function business()
    {
        return array(
            'Arts, entertainment and recreation',
            'Banking & finance',
            'Beauty industry',
            'Educational services',
            'Health care and social assistance',
            'Information Technology',
            'Information and cultural industries',
            'Insurance Insurance',
            'Manufacturing Manufacturing',
            'Mining, quarrying, and oil and gas',
            'Non-Governmental Organisations',
            'Other services',
            'Public administration',
            'Real estate, rental and leasing',
            'Religious Organisations',
            'Retail trade',
            'Transportation and warehousing',
            'Utilities',
            'Waste management',
            'Wholesale trade',
        );
    }
}
