<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use App\Models\User;
use App\Models\EmailQueue;
use App\Models\Company;
use App\Models\CabinClass;
use App\Models\Product;
use App\Models\Folder;
use App\Events\NotificationEvent;
use App\Models\AdminNotification;
use App\Events\AdminNotificationEvent;
use Illuminate\Support\Facades\Mail;

use App\Http\Controllers\RatingController;
use Carbon\Carbon;


class UserController extends Controller
{

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
        $this->middleware('auth:admin', ['except' => ['renewExpiredUser']]);

        $adminUser = auth()->guard('admin')->user();

        if (!$adminUser)
        {
            return response()->json(['error' => 'Unauthorized.'], 401);
        }

    }


    public function index(Request $req) {

        if (isset( $req->inactive ) && $req->inactive == 1) {

            $users = User::where('active', '!=', 1)->with('company:id,name')->with('company.cabinClasses')->get();

        }else{

            $users = User::with('company:id,name')->with('company.cabinClasses')->get();
        }



        return response()->json($users);
    }
    public function inactiveUsers(Request $req) {

        $users = User::where('active', '!=', 1)->with('company:id,name')->with('company.cabinClasses')->get();


        return response()->json($users);
    }
    //

    public function create(Request $req) {

        $validator = Validator::make($req->all(), [
            'first_name' => 'required',
            'last_name' => 'required',
            'company_name' => 'required',
            'email' => 'required|unique:users|email',
            'password' => [
                'required',
                'min:6',
                'confirmed',
                'regex:/[A-Z]/',    // At least one uppercase letter
                'regex:/[0-9]/'     // At least one number
            ]
        ], [
            'password.regex' => 'Password must contain at least one uppercase letter and one number.'
        ]);
        if ($validator->fails()) {
            //throw new ValidationException($validator);
            # var_dump($validator->errors()->first());die();
            return response()->json(['error' => $validator->errors()->first()], 500);

        }

        $req->company_name = ucwords( strtolower( $req->company_name ) );

        $company = Company::where('name', $req->company_name)->first();

        $companyFolder = null;
        
        $cabinClasses = $req->cabin_classes;

        #var_dump($cabinClasses);die();

        $user = User::create([
            'first_name' => $req->first_name,
            'last_name' => $req->last_name,
            'email' => $req->email,
            'active' => 0,
            'password' => Hash::make($req->password)
        ]);

        if (isset($req->req_from) && $req->req_from == 'registration') {


            // $notification = new AdminNotification([
            //     'cta_label' => 'New User registered',
            //     'instigator_id' => $user->id, 
            //     'message' => $user->first_name.' '.$user->last_name.' registered.',
            //     'href' => 'users/'.$user->id,
            // ]);
            // $notification->save();


            $notification = AdminNotification::create([
                'cta_label' => 'New User registered',
                // 'instigator_id' => $user->id, 
                // 'message' => $user->first_name.' '.$user->last_name.' registered.',
                // 'href' => 'users/'.$user->id

            ]);
            $notification->instigator_id = $user->id;
            $notification->message = $user->first_name.' '.$user->last_name.' registered.';
            $notification->href = 'users/'.$user->id;
            $notification->save();


            $notification = $notification->toArray();
            $notification['instigator'] = $user;

            event(new AdminNotificationEvent($notification));

            $mail = EmailQueue::create([
                'label' => 'New User registered',
                'type' => '0',
                'user_id' => $user->id,
                'info' => $user->first_name.' '.$user->last_name.' registered.',
                'to' => $user->email
            ]);


            // $emails = ['a.bellamio@mandarino.agency', 'f.quagliotto@mandarino.agency', 'a.zerbinati@mandarino.agency', $user->email];
            // $emails = ['a.zerbinati@mandarino.agency', $user->email];

            // Mail::send('email.userRegistration', [
            //     'first_name' => $user->first_name, 
            //     'last_name' => $user->last_name,
            //     'email' => $user->email,
            //     'company' => $req->company_name
            // ], function($message) use($req, $user, $emails){
            //     $message->to($emails);
            //     $message->subject('AVIO Interiors - New user registration');
            // });

        }


        $existing_company = 0;
        if ($company)
        {
            $user->company_id = $company->id;
            $existing_company = 1;
        } else {
            $company = Company::create(['name' => $req->company_name]);

            # var_dump($company->id);die();

            $user->company_id = $company->id;

            // Da spostare in fase di attivazione

            /*
            Storage::disk('fake_s3')->makeDirectory($company->name);
            $path = $company->name;
            $companyFolder = Folder::create(['path' => $path]);
            $company->folder_id = $companyFolder->id;
            $companyFolder->company_id = $company->id;
            */

            $company->save();

            if (isset($req->req_from) && $req->req_from == 'registration') {


                // $notification = new AdminNotification([
                //     'cta_label' => 'New Company',
                //     'instigator_id' => $user->id, 
                //     'message' => $user->first_name.' '.$user->last_name.' created a company '.$company->name.'.',
                //     'href' => 'companies/'.$company->id,
                // ]);
                // $notification->save();

                $notification = AdminNotification::create([
                    'cta_label' => 'New Company',
                    // 'instigator_id' => $user->id, 
                    // 'message' => $user->first_name.' '.$user->last_name.' created a company '.$company->name.'.',
                    // 'href' => 'companies/'.$company->id
                ]);
                $notification->instigator_id = $user->id;
                $notification->message = $user->first_name.' '.$user->last_name.' created a company '.$company->name.'.';
                $notification->href = 'companies/'.$company->id;
                $notification->save();


                $notification = $notification->toArray();
                $notification['instigator'] = $user;

                // $emails = ['a.bellamio@mandarino.agency', 'f.quagliotto@mandarino.agency', 'a.zerbinati@mandarino.agency'];
                // $emails = ['a.zerbinati@mandarino.agency'];

                $mail = EmailQueue::create([
                    'label' => 'New Company',
                    'type' => '1',
                    'user_id' => $user->id,
                    'info' => $user->first_name.' '.$user->last_name.' created a company '.$company->name.'.',
                    'to' => $user->email
                ]);

                // Mail::send('email.companyCreation', [ 
                //     'first_name' => $user->first_name, 
                //     'last_name' => $user->last_name,
                //     'email' => $user->email,
                //     'company' => $req->company_name
                // ], function($message) use($req, $user, $emails){
                //     $message->to($emails);
                //     $message->subject('AVIO Interiors - New company creation after user registration');
                // });




                event(new AdminNotificationEvent($notification));
            }

        }

        foreach($cabinClasses as $cabinClass) {
            if ($company->cabinClasses->count() <= 4 && array_key_exists('name', $cabinClass) )
            {
                if($existing_company == 1){
                    $cabin = CabinClass::where([
                        ['name', $cabinClass['name'] ], 
                        ['company_id', $company->id] ]
                    )->first();

                    // Nel caso non è ancora presente nella Company
                    if (!$cabin) {
                        $cabin = new CabinClass(['name' => $cabinClass['name'], 'company_id' => $company->id]);
                        $company->cabinClasses()->save($cabin);
                    }

                }else{
                    $cabin = new CabinClass(['name' => $cabinClass['name'], 'company_id' => $company->id]);

                    $company->cabinClasses()->save($cabin);

                    # $cabin = CabinClass::create(['name' => $cabinClass['name'], 'company_id' => $company->id]);
                }
                # $cabin->company_id = $company->id;

                // Da spostare in fase di attivazione

                /*
                Storage::disk('fake_s3')->makeDirectory($company->name.'/'.$cabin->name);
                $folder = Folder::create([
                    'path' => $company->name.'/'.$cabin->name
                ]);
                if ($companyFolder) {
                    $folder->parent_id = $companyFolder->id;
                }
                $folder->company_id = $company->id;
                $folder->save();
                */

                # $cabin->save();

                foreach($cabinClass['products'] as $product)
                {

                    $p = new Product([
                        'serial_number' => $product['serial_number'],
                        'cabin_class_id' => $cabin->id,
                        'user_id' => $user->id,
                        'active' => 0,
                        'user_first_name' => $user->first_name,
                        'user_last_name' => $user->last_name,
                    ]);
                    # $p = Product::create(['serial_number' => $product['serial_number']]);
                    # $p->cabin_class_id = $cabin->id;
                    # $p->save();
                    
                    $cabin->products()->save($p);

                }
            }

        }

        //$user = User::create($req->only(['name', 'email']));

        if ($req->req_from == 'registration') {

            $user->save();
            return response()->json(["status"=> 'ok',"user" => $user], 200);
        }

        $user->save();
        return response()->json($user);

    }

    public function show($id, Request $request) {
        $user = User::where('id', $id)->with('company')->with('company.cabinClasses')->first();

        if ($user && $user->company) {
            foreach($user->company->cabinClasses as $cabinClass)
            {
                $cabinClass->products = Product::where('cabin_class_id', $cabinClass->id)->get();
            }
        };

        if (!$user) {
            return response()->json(['error' => 'User not found'], 404);
        };

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


    public function validateCompany($company_id = null)
    {
        if ($company_id != null) {
            $company = Company::where('id', $company_id)->with('cabinClasses')->with('cabinClasses.products')->with('users')->with('folder')->first();

            if ($company && $company->active == 0) {

                if (count($company->folder) == 0) {
                    
                    Storage::disk('fake_s3')->makeDirectory($company->name);
                    $path = $company->name;
                    $companyFolder = Folder::create(['path' => $path]);
                    $company->folder_id = $companyFolder->id;
                    $companyFolder->company_id = $company->id;

                    if (count( $company->cabinClasses ) > 0) {
                        foreach ($company->cabinClasses as $kk => $v_cabin) {

                            $v_cabin->removable = true;

                            Storage::disk('fake_s3')->makeDirectory($company->name.'/'.$v_cabin->name);
                            $folder = Folder::create([
                                'path' => $company->name.'/'.$v_cabin->name
                            ]);
                            if ($companyFolder) {
                                $folder->parent_id = $companyFolder->id;
                            }
                            $folder->company_id = $company->id;
                            $folder->save();

                            if (count($v_cabin->products) > 0) {
                                foreach ($v_cabin->products as $k => $value) {
                                    $v_cabin->products[$k]->active = ($v_cabin->products[$k]->active == 1 ? true : false);
                                }
                            }

                        }
                    }
                    $company->active = 1;
                    $company->save();
                }
            }
            // Caso in cui la Company esiste, è attiva, ma un utente ha richiesto una classe non presente prima
            if ($company && $company->active == 1) {
                //if (count($company->cabinClasses) != count($company->folder) ) {

                    $company->missing_folders = 0;


                    $folder_list = [];
                    foreach ($company->folder as $k => $v_folder) {
                        
                        $name_expl = explode("/", $v_folder->path);
                        $name = $name_expl[count($name_expl)-1];

                        $folder_list[ $name ] = $v_folder->path;
                    }
                    foreach ($company->cabinClasses as $key => $v_cabin) {

                        $check_folder = Folder::where('path', $company->name.'/'.$v_cabin->name)->first();

                        if (!$check_folder) {
                            // Se manca va creata
                            if ( !array_key_exists($v_cabin->name, $folder_list) ) {

                                $v_cabin->removable = true;

                                Storage::disk('fake_s3')->makeDirectory($company->name.'/'.$v_cabin->name);
                                $folder = Folder::create([
                                    'path' => $company->name.'/'.$v_cabin->name
                                ]);
                                if ($company->folder_id) {
                                    $folder->parent_id = $company->folder_id;
                                }
                                $folder->company_id = $company->id;
                                $folder->save();

                                if (count($v_cabin->products) > 0) {
                                    foreach ($v_cabin->products as $k => $value) {
                                        $v_cabin->products[$k]->active = ($v_cabin->products[$k]->active == 1 ? true : false);
                                    }
                                }
                            }
                        }
                    }
            }

            if (!$company) {
                return response()->json(['error' => 'Company not found.'], 404);
            }

            return response()->json(['company' => $company], 200);
        }
    }


    public function edit($id, Request $request) {
        $validator = Validator::make($request->all(), [
            'first_name' => 'required',
            'last_name' => 'required',
            'email' => 'required|unique:users,email,'.$id.'|email',
            'password' => 'min:6|confirmed'
        ]);

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }

        $user = User::find($id);

        if (!$user) {
            return response()->json(['error' => 'User not found'], 404);
        }

        $user->first_name = $request->first_name;
        $user->last_name = $request->last_name;

        if ($user->active == 0 && $request->active == true) {
            $this->validateCompany($user->company_id);
        }

        $user->active = ($request->active == true ? 1 : 0);

        if ($request->password) {
            $user->password = Hash::make($request->password);
        }

        if ($request->selected_company) {
            $company = Company::where('name', $request->selected_company)->first();

            $user->company_id = $company->id;
        }

        $user->save();

        return response()->json(['success' => 'User updated']);

    }

    public function delete($id, Request $request) {

        $user = User::find($id);

        $user->delete();
        return response()->json(['success' => 'User deleted successfully.'], 200);


    }

    public function fireNotification(Request $request) {
        return response()->json(['success' => 'Notification fired successfully.'], 200);
    }


    public function activateUser(Request $request)
    {
        $user_id = $request->user_id;
        $user = User::find($user_id);
        if ($user) {
            if ($user->active != 1) {
                $user->active = 1;
                if (isset($user->company_id) && $user->company_id > 0) {
                    $this->validateCompany($user->company_id);
                }

            }else{
                $user->active = 0;
            }
        }
        $user->save();

        return response()->json(['info' => 'User successfully activated'], 200);
    }

    public function activateUsers(Request $request)
    {
        $all_user_to_activate = $request->users_list;

        foreach ($all_user_to_activate as $key => $value) {
            if ($value != null && is_bool( $value ) && $value == true) {

                $user_id = $key;
                $user = User::find($user_id);
                if ($user) {
                    if ($user->active != 1) {
                        $user->active = 1;
                        if (isset($user->company_id) && $user->company_id > 0) {
                            $this->validateCompany($user->company_id);
                        }
                    }else{
                        # $user->active = 0;
                    }
                }
                $user->save();     
            }
        }

        return response()->json(['info' => 'Users successfully activated'], 200);
    }


    public function renewExpiredUser(Request $request)
    {
        $token = $request->token;
        $request->rating1 = $request->rating_1;
        $request->rating2 = $request->rating_2;
        $request->rating3 = $request->rating_3;
        $request->rating4 = $request->rating_4;

        if ($token != '') {
            $user = User::where('renewal_token', $token)->first();
            if ($user) {
                $request->email = $user->email;
                $res = (new RatingController)->save($request);

                if (isset($res->original['status']) && $res->original['status'] == 'ok') {
                    $user->active = 1;
                    $user->expired = 0;
                    $user->renewal_token = NULL;
                    $user->renew_date = Carbon::now();

                    $user->save();

                    return response()->json(['status' => 'ok', 'info' => 'all done'], 200);


                }else{

                    return response()->json(['error' => 'Problem saving ratings'], 500);
                }

            }else{
                return response()->json(['error' => 'No user found'], 404);

            }
        }
    }

}
