<?php /** @noinspection PhpUnhandledExceptionInspection */
/** @noinspection PhpUndefinedMethodInspection */

/** @noinspection PhpUndefinedClassInspection */

namespace App\Http\Controllers\Admin;

use App\AdminAccessRight;
use App\Company;
use App\CompanyDirector;
use App\CompanyStatus;
use App\DataTables\Admin\CompanyDataTable;
use App\DataTables\SingleUserDataTable;
use App\Opt\CompanyTrait;
use App\Role;
use App\Services\OTPService;
use App\Tools\SmsTools;
use App\User;
use App\UserSenderId;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class AdminCompanyController extends Controller
{

    public  function index(CompanyDataTable $company)
    {
        return $company->render('admin.company.index');
    }

    public  function create(Request $request)
    {
        if($request->isMethod('Post')):

            $this->validate($request,

                [

                    'name' =>'required|unique:companies',
                    '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',
                    'contact_person_id' =>'sometimes|nullable',
                    'contact_person_designation' =>'sometimes|nullable',
                    'contact_person_phone' =>'required|unique:companies|digits_between:10,20',
                    'contact_person_email' =>'required',
                    'username' =>'required|min:6|unique:users',

                ]
            );

            // Validate phone number has verified OTP for registration
            $otpService = new OTPService();
            $phoneValidation = $otpService->validatePhoneForRegistration($request->input('contact_person_phone'), 10);

            if (!$phoneValidation['valid']) {
                return redirect()->back()
                    ->withInput(Input::all())
                    ->withErrors(['contact_person_phone' => $phoneValidation['message'] ?? 'Phone number not verified']);
            }


            $contains = Str::contains($request->input('contact_person_email'), ['@']);

            if(!$contains)
                return redirect()->back()->withInput(Input::all())->withErrors('This is not a valid email');

            $verify = User::query()->where('email',$request->input('contact_person_email'))->first();

            if($verify)
                return redirect()->back()->withInput(Input::all())->withErrors('the email '.$request->input('contact_person_email') .' has already been taken');

            $records = $request->all();

            $records['nature_of_business']          = empty($request->input('nature_of_business')) ? 'N/A' : $request->input('nature_of_business');
            $records['date_of_incorporation']       = empty($request->input('date_of_incorporation')) ? 'N/A' : $request->input('date_of_incorporation');
            $records['contact_person_phone']        = SmsTools::format_gh_number( $request->input('contact_person_phone'));
            $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('physical_address')) ? 'N/A' : $request->input('physical_address');
            $records['postal_address']              = empty($request->input('postal_address')) ? 'N/A' : $request->input('postal_address');


            $result = $this->generateUserInfo($request);
            $result['created_by'] = 'npontu';



            DB::beginTransaction();

                $user = User::query()->create($result);

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

                $user->credit()->create([
                    'username' => $user->username,
                    'price' => '0.024',
                    '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

                    if(isset($sendor_ids))
                        $this->saveSenderId($sendor_ids,$user);          //then we save the sender Id here

                    if(isset($directors))
                        $this->saveDirectors($directors,$company);       //we save the company's director here

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

                    $company->update($status);  //updates the company status to 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){}


                    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){}



                    $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";
                    $this->sendSms($msg,$company->users->phone_number);


                  return redirect()->route('admin.root.company')->with('success','Company Successfully Registered');
            endif;

           return view('admin.company.create');

    }

    private function verifyUsername($string)
    {
        $length = 2;
        $query = User::query()->where('username',$string)->first();
        //if query returns true that means we ought to regenerate the user the name.

        //while $query remains true
        while($query):
            $random = substr(str_shuffle(str_repeat($x='0123456789',ceil($length/strlen($x)))),1,$length);
            $string = $string.$random;
            break;
        endwhile;

        return $string;
    }

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

        $demo = strtolower($acronym.$words[0]);

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

        $username =  $this->verifyUsername($demo);

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

        return $inputs;
    }

    private function saveFiles(Request $request)
    {

        $records = array();

        if($request->has('business_document'))
        {

            $bc = $request->file('business_document');
            $records['business_document'] = date('Y-m-d h:i:s').'_'.$bc->getClientOriginalName();
            $bc->storePubliclyAs('public/business_doc', $records['business_document']);

        }

        if($request->has('business_logo'))
        {

            $bc = $request->file('business_logo');
            $records['business_logo'] = date('Y-m-d h:i:s').'_'.$bc->getClientOriginalName();
            $bc->storePubliclyAs('public/business_logo', $records['business_logo']);

        }

        if($request->has('sender_id_document'))
        {

            $sendID = $request->file('sender_id_document');
            $records['sender_id_document'] = date('Y-m-d h:i:s').'_'.$sendID->getClientOriginalName();
            $sendID->storePubliclyAs('public/sender_docs', $records['sender_id_document']);

        }

        if($request->has('contact_person_id'))
        {

            $contactID = $request->file('contact_person_id');
            $records['contact_person_id'] = date('Y-m-d h:i:s').'_'.$contactID->getClientOriginalName();
            $contactID->storePubliclyAs('public/contact_person', $records['contact_person_id']);

        }

        return $records;
    }

    private function saveSenderId(array  $senderIds, $user)
    {
        foreach ($senderIds as $sendor_id):

            $today = date('Y-m-d h:i:s');
            $registerIds = new UserSenderId;
            $registerIds->user_id = $user->id;
            $registerIds->sender_id = $sendor_id['Name'];
            $registerIds->created_at = Carbon::parse($today);
            $registerIds->updated_at = Carbon::parse($today);
            $registerIds->save();

        endforeach;
    }

    private function saveDirectors(array $directors, $company)
    {
        foreach ($directors as $director):
            $array['company_id'] = $company->id;
            $array['name'] = $director['Name'];
            $array['designation'] = $director['Designation'];
            CompanyDirector::query()->create($array);

        endforeach;
    }

    private function setStatus($company)
    {

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

        return $expose;

    }

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

    public  function edit(Request $request,$id)
    {
        $company = Company::query()->find($id);
        $sends = json_encode(UserSenderId::query()->where('user_id',$company->users->id)->select('id','sender_id as name')->get()->toArray());
        $dirs = json_encode($company->directors()->select('id','name','designation')->get()->toArray());


        if($request->isMethod('Post')):

            $this->validate($request,[
//                'date_of_incorporation' =>'required',
//                'legal_status' =>'required',
//                'nature_of_business' =>'required',
                'name' =>'required|unique:companies,name,'.$id,
                'company_phone_number' =>'required|digits_between:10,20',
                'contact_person' =>'required',
                'contact_person_designation' =>'required',
                'contact_person_phone' =>'required|digits_between:10,20',
                'contact_person_email' =>'required',
            ]);

            $contains = Str::contains($request->input('contact_person_email'), ['@']);

            if(!$contains)
                return redirect()->back()->withInput(Input::all())->withErrors('This is not a valid email');

            $verify = User::query()->where('email',$request->input('contact_person_email'))->first();

            if($verify && $company->users->email != $verify->email)
                return redirect()->back()->withInput(Input::all())->withErrors('the email '.$request->input('contact_person_email') .' has already been taken');

            $records = $request->all();

//            $sender_ids   = json_decode($records['sender_ids'], true);

//            $directors   = json_decode($records['items'], true);

//            if($sender_ids == null)
//                redirect()->back()->withErrors('All Fields Are Required');

//            /** Validation check on company directors **/
//            if(count(@$directors) < 1)
//                return redirect()->back()->withInput(Input::all())->withErrors('Company directors field should have a Minimum of one director');

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


            DB::beginTransaction();

            if (!empty($company->users))
                $user   = $company->users->update($result);

            $company->update($records);

             $status = $this->editSetStatus($company);

                //update uploaded files
                $output = $this->editSavedFiles($request,$company);
                if(!empty($output))
                    $company->update($output);
                //then we edit the sender Id here
//                if (!empty($user))
//                    $this->editSavedSenderId($sender_ids,$user);
                    // we edit the company's director here
//                    $this->editSavedDirectors($directors,$company);

            DB::commit();

            return redirect()->route('admin.root.company')->with('success','Company Successfully Updated');

        endif;


        return view('admin.company.edit',compact('company','sends','dirs'));

    }

    private function editUserInfo(Request $request)
    {

        $inputs['phone_number'] = SmsTools::format_gh_number($request->input('company_phone_number'));
        $inputs['full_name'] = $request->input('name');
        $inputs['organisation'] = $request->input('name');;
        $inputs['website_url'] = !empty($request->input('website_url')) ? $request->input('website_url') : null;
        $inputs['email'] = $request->input('contact_person_email');
        $inputs['role_id'] = Role::where('name', $request->input('register_as'))->first()->id;
        $inputs['location'] = $request->input('physical_address');

        return $inputs;
    }

    private function editSavedFiles(Request $request,$company)
    {
        $records = array();

        if($request->hasFile('business_document')):

            $bc = $request->file('business_document');
            $records['business_document'] = date('Y-m-d h:i:s').'_'.$bc->getClientOriginalName();
            $bc->storePubliclyAs('public/business_doc', $records['business_document']);
            Storage::delete('public/business_doc/'.$company->business_document);

        endif;

        if($request->hasFile('sender_id_document')):

            $sendID = $request->file('sender_id_document');
            $records['sender_id_document'] = date('Y-m-d h:i:s').'_'.$sendID->getClientOriginalName();
            $sendID->storePubliclyAs('public/sender_docs', $records['sender_id_document']);
            Storage::delete('public/business_doc/'.$company->sender_id_document);

            endif;

        if($request->hasFile('contact_person_id')):

                $contactID = $request->file('contact_person_id');
                $records['contact_person_id'] = date('Y-m-d h:i:s').'_'.$contactID->getClientOriginalName();
                $contactID->storePubliclyAs('public/contact_person', $records['contact_person_id']);
                Storage::delete('public/business_doc/'.$company->contact_person_id);
             endif;

        return $records;
    }

    private function editSavedSenderId(array  $senderIds,$user)
    {
        foreach ($senderIds as $sendor_id):
            if(empty($sendor_id['id'])):

                $save['user_id']  = $user->id;
                $save['name']        = $sendor_id['name'];

                else:
            $find = UserSenderId::query()->find($sendor_id['id']);

            $edit['sender_id']  = $sendor_id['name'];

            $find->update($edit);
            endif;

        endforeach;
    }

    private function editSavedDirectors(array $directors,$company)
    {
        foreach ($directors as $director):
            if(empty($director['id'])):

                $save['company_id']  = $company->id;
                $save['name']        = $director['name'];
                $save['designation'] = $director['designation'];


                CompanyDirector::query()->create($save);

             else:
            $find = CompanyDirector::query()->find($director['id']);

            $edit['name']  = $director['name'];
            $edit['designation']  = $director['designation'];

            $find->update($edit);

            endif;


        endforeach;
    }

    private function editSetStatus($company)
    {

       $user = CompanyStatus::query()->where('company_id',$company->id)->first();

       if(!empty($user)):
           $user->update([
               'status'=> 3
           ]);
       endif;


    }

    public  function delete($id)
    {
        $company = Company::query()->find($id);
        try {
            DB::beginTransaction();
                $company->history()->delete();
            DB::commit();
        } catch (\Exception $e) {}

        return redirect()->back()->withErrors("Company Successfully Deleted");
    }


    use CompanyTrait;



    public function translate($string)
    {
            return $string;
    }




}



















