<?php

namespace App\Http\Controllers\V1\Admin;

use App\Http\Controllers\Controller;
use App\Http\Controllers\V1\GlobalConstantsPermissions;
use App\Http\Controllers\V1\GlobalConstantsRoles;
use App\Models\ClientAddress;
use App\Models\Organization;
use App\Models\Quotation;

use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Spatie\Permission\Models\Role;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{
    public function dummyAdminRegister(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6|confirmed',
                'address_line_1' => 'required|string',
                'address_line_2' => 'nullable|string',
                'pincode' => 'required|string',
                'state' => 'required|string',
                'city' => 'required|string',
                'country' => 'required|string',
                'organizationName' => 'required|string',

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $billingAddress = new ClientAddress();
            $billingAddress->address_line_1 = $request->address_line_1;
            $billingAddress->address_line_2 = $request->address_line_2;
            $billingAddress->pincode = $request->pincode;
            $billingAddress->state = $request->state;
            $billingAddress->city = $request->city;
            $billingAddress->country = $request->country;
            $billingAddress->save();

            $newOrganization = new Organization();
            $newOrganization->name = $request->organizationName;
            $newOrganization->billing_address_id = $billingAddress->id;

            $newUser = new User();
            $newUser->password = Hash::make($request['password']);
            $newUser->name = $request->name;
            $newUser->email = $request->email;

            //$newUser->last_login_at = Carbon::now();
            $new = new GlobalConstantsPermissions();
            $new->assignPermissionToUser(GlobalConstantsRoles::Accountant);
            $role = Role::where('name', GlobalConstantsRoles::SuperAdmin)->first();
            $role->givePermissionTo(GlobalConstantsPermissions::addProducts);
            $newUser->assignRole($role);
            $newUser->save();
            $token = JWTAuth::fromUser($newUser);
            $response = ['token' => $token];
            $response['userData'] = $newUser;
            return $this->sendResponse($response, 'Registered Successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function registerUser(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6|confirmed',
                'role' => 'required|string|exists:roles,name',
                'store_id' => 'required|integer|exists:stores,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            if ($request->role == 'SuperAdmin') {
                return $this->sendResponse([], 'Sorry you can\'t be super admin.It\'s our property', true);
            }

            $newUser = new User();
            $newUser->password = Hash::make($request['password']);
            $newUser->name = $request->name;
            $newUser->email = $request->email;
            $newUser->store_id = $request->store_id;

            $getOrganization=Organization::query()->orderBy('id', 'DESC')->first();
            $organizationId=$getOrganization->id;

            $newUser->organization_id = $organizationId;
            // $newUser->last_login_at = Carbon::now();

            $role = Role::where('name', $request->role)->first();
            $newUser->assignRole($role);
           // $newUser->save();
            $token = JWTAuth::fromUser($newUser);
            $response = ['token' => $token];
            $response['userData'] = $newUser;
            return $this->sendResponse($response, 'Registered Successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
        }
    }

    public function registerSuperAdminUser(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6|confirmed',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newUser = new User();
            $newUser->password = Hash::make($request['password']);
            $newUser->name = $request->name;
            $newUser->email = $request->email;

            // $newUser->last_login_at = Carbon::now();

            $role = Role::where('name', GlobalConstantsRoles::SuperAdmin)->first();
            $newUser->assignRole($role);
            $newUser->save();
            $token = JWTAuth::fromUser($newUser);
            $response = ['token' => $token];
            $response['userData'] = $newUser;
            return $this->sendResponse($response, 'Super Admin Registered Successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function superAdminLogin(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email',
                'password' => 'required|string|min:6',
                'firebase_device_token' => 'string'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            // $getRole = Role::where('name', GlobalConstantsRoles::Accountant)->first();
            // $new =new GlobalConstantsPermissions();
            // $new->assignPermissionToUser($getRole);
            $user = User::where('email', $request->email)->whereHas(
                'roles', function ($q) {
                $q->where('name', GlobalConstantsRoles::SuperAdmin);
            })->first();

            if ($user) {
                if (Hash::check($request->password, $user->password)) {
                    Auth::login($user);
                    $getUser = User::query()->where('email', $request->email)->first();
//                    $getUser->firebase_device_token= $request->firebase_device_token;
                    $getUser->save();
                    $token = JWTAuth::fromUser($user);
                    $response = ['token' => $token];
                    $response['userData'] = $user;
//                    $response['role'] = $user->roles->first();
                    $response['permissions'] = $user->getAllPermissions();
                    return $this->sendResponse($response, 'Login Success', 200);
                } else {
                    return $this->sendError('Password mismatch', [], 422);
                }
            } else {
                return $this->sendError('User does not exist or user doesn\'t have access', [], 200);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function userLogin(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email',
                'password' => 'required|string|min:6',
                'firebase_device_token' => 'string'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = User::where('email', $request->email)->with(['organization'])->first();
            if (!is_null($user)) {
                if (Hash::check($request->password, $user->password)) {
                    Auth::login($user);
                    $getUser = User::query()->where('email', $request->email)->first();
//                    $getUser->firebase_device_token= $request->firebase_device_token;
                    $getUser->save();
                    $token = JWTAuth::fromUser($user);
                    $response = ['token' => $token];
                    $response['userData'] = $user;
//                    $response['role'] = $user->roles->first();
                    $response['permissions'] = $user->getAllPermissions();
                    return $this->sendResponse($response, 'Login Success', 200);
                } else {
                    return $this->sendError('Password mismatch', [], 422);
                }
            } else {
                return $this->sendError('User does not exist or user doesn\'t have access', [], 200);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function forgetPassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }

        $user = User::where('email', $request->email)->first();
        if (!$user) {
            return $this->sendError('Email Id does Not Exist', [], 403);
        }

        $otp = rand(1000, 9999);
        $user->forget_password_otp = $otp;
        $user->forget_password_timestamp = Carbon::now();
        $user->save();

        $to_name = $user->name;
        $to_email = $user->email;

        $data = array('otp' => $otp);

        Mail::send('emails.forgetPassword', $data, function ($message) use ($to_name, $to_email) {

            $message->to($to_email, $to_name)
                ->subject('Otp For New Password');
            $message->from(env('MAIL_FROM_ADDRESS'), 'MaarsLMS System Mail');

        });

        return $this->sendResponse([], 'Otp Send Successfully', true);


    }

    public function changeForgetPassword(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|string|email|max:255',
                'otp' => 'required|numeric',
                'new_password' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $user = User::where('email', $request->email)->first();
            if (!$user) {
                return $this->sendError('Email Id does Not Exist', [], 200);
            }


            $to = Carbon::createFromFormat('Y-m-d H:i:s', $user->forget_password_timestamp);
            $from = Carbon::createFromFormat('Y-m-d H:i:s', Carbon::now());

            $time_diff = $to->diffInMinutes($from);
            if ($time_diff > 5) {
                return $this->sendError('Time Limit Expired', [], 200);
            }

            if ($user->forget_password_otp != $request->otp) {
                return $this->sendError('Invalid Otp ! ', [], 200);
            }

            $user->password = Hash::make($request->new_password);
            $user->save();

            return $this->sendResponse([], 'Password Changed Successfully', true);


        } catch (Exception $e) {
            return $this->sendError('something Went Wrong', [$e->getMessage()], 413);
        }
    }

    public function sendQuotation(Request $request)
{
    $validator = Validator::make($request->all(), [
        'quotation_id' => 'required|numeric',
        'emails' => 'nullable|array',
        'emails.*' => 'nullable|email',
    ]);
    if ($validator->fails()) {
        return $this->sendError('Validation Error.', $validator->errors());
    }

    $quotation = Quotation::with('client')->findOrFail($request->quotation_id);

    $client_email = $quotation->client->company_email;

    $to_email = $client_email;

    $pdf=$request->pdf_file;

    if (!empty($request->emails)) {
        $additional_emails = implode(',', $request->emails);
        $to_email .= ',' . $additional_emails;
    }

    $data = [
        'quotation' => $pdf,
    ];

    Mail::send('emails.sendQuotation', $data, function ($message) use ($to_email) {
        $message->to($to_email)
            ->subject('Quotation');
        $message->from(env('MAIL_FROM_ADDRESS'), 'MaarsLMS System Mail');
    });

    return $this->sendResponse([], 'Quotation Sent Successfully', true);
}
public function saveImage($image,$productName){
    $imageName = $productName.'-'.rand(100,9999).'.webp';

    $destinationPath = public_path('productimage\\'.$imageName);
    if(env('APP_ENV')=='prod'){
        $destinationPath =  public_path('productimage/'.$imageName);
    }
    $img = Image::make(file_get_contents($image))
        ->resize(300, null)
        ->save($destinationPath,80,'webp');

    return '/productimage/'.$imageName;
}
public function createOrganization(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string',
            'organization_email'=>'string|email',
            'organization_contact_number'=>'string',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $billingAddress = new ClientAddress();
        $billingAddress->address_line_1 = $request->address_line_1;
        $billingAddress->address_line_2 = $request->address_line_2;
        $billingAddress->pincode = $request->pincode;
        $billingAddress->state = $request->state;
        $billingAddress->city = $request->city;
        $billingAddress->country = $request->country;
        $billingAddress->save();
        $newOrganization = new Organization;
        $newOrganization->billing_address_id=$billingAddress->id;
        $newOrganization->name = $request->name;
        $newOrganization->organization_email = $request->organization_email;
        $newOrganization->organization_contact_number = $request->organization_contact_number;
        if ($request->logo != "") {
            if (!str_contains($request->logo, "http")) {
                $newOrganization->logo = $this->saveImage($request->logo, $request->name);
            }
        }
        $newOrganization->save();
        // $billingAddress->client_id=$newOrganization->id;
            $billingAddress->address_for='organization';
            $billingAddress->save();
        return $this->sendResponse([], 'Organization created successfully', true);
    } catch (Exception $e) {
        return $this->sendError('Something went wrong', $e->getMessage(), 413);
    }
}
public function editOrganization(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|exists:organizations,id',
            'name' => 'nullable|string',
            'organization_email'=>'nullable|string|email',
            'organization_contact_number'=>'nullable|string',
            'address_line_1'=>'nullable',
            'address_line_2'=>'nullable',
            'pincode'=>'nullable',
            'state'=>'nullable',
            'city'=>'nullable',
            'country'=>'nullable',

        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $editOrganization = Organization::query()->where('id', $request->id)->first();
        $address= $editOrganization->billing_address_id;
        if ($request->has('name')) {
            $editOrganization->name = $request->name;
        }
        if ($request->has('organization_email')) {
            $editOrganization->organization_email = $request->organization_email;
        }
        if ($request->has('organization_contact_number')) {
            $editOrganization->organization_contact_number = $request->organization_contact_number;
        }
      //  $editOrganization->save();
      $editAddress=ClientAddress::query()->where('id',$address)->first();
      if ($request->has('address_line_1')) {
        $editAddress->address_line_1 = $request->address_line_1;
    }
    if ($request->has('address_line_2')) {
        $editAddress->address_line_2 = $request->address_line_2;
    }
    if ($request->has('pincode')) {
        $editAddress->pincode = $request->pincode;
    }
    if ($request->has('state')) {
        $editAddress->state = $request->state;
    }
    if ($request->has('city')) {
        $editAddress->city = $request->city;
    }
    if ($request->has('country')) {
        $editAddress->country = $request->country;
    }
    $editAddress->save();
        return $this->sendResponse([], 'Organization updated successfully', true);
    } catch (Exception $e) {
        return $this->sendError('Something went wrong', $e->getMessage(), 413);
    }
}
public function getAllOrganization(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $query = Organization::query()->with(['billing_address']);
        $count = $query->count();
        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        $getProducts = $query->get();
        if (count($getProducts) > 0) {
            return $this->sendResponse(["organization" => $getProducts, 'count' => $count], 'Data fetch successfully');
        } else {
            return $this->sendResponse([], 'No organization are available', false);
        }
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function getOrganizationById(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|exists:organizations,id',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $getOrganization = Organization::query()->where('id', $request->id)->with(['billing_address'])->first();

        return $this->sendResponse(["organization" =>$getOrganization], 'Data fetch successfully', true);

    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function deleteOrganizationById(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|exists:organizations,id',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $user = Organization::query()->where('id', $request->id)->first();
        $user->delete();
        return $this->sendResponse([], 'Organization deleted successfully', true);
    } catch (Exception $e) {
        return $this->sendError('Something went wrong', $e->getMessage(), 413);
    }
}

}
