<?php

namespace App\Http\Controllers;
use App\Models\Banner;
use App\Models\Product;
use App\Models\Category;
use App\Models\PostTag;
use App\Models\PostCategory;
use App\Models\Post;
use App\Models\Colors;
use App\Models\Size;
use App\Models\Cart;
use App\Models\Brand;
use App\Models\NFT;
use App\Models\ProductReview;
use App\User;
use Auth;
use Session;
use Newsletter;
use DB;
use Hash;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Mail;
use App\Mail\SendMail;
use Inertia\Inertia;

class FrontendController extends Controller
{
   
    public function index(Request $request){
        return redirect()->route($request->user()->role);
    }

    public function home(){
        return Inertia::render('Home');
    }   

    public function about(){
        return Inertia::render('About');
    }

    public function roadmap(){
        return Inertia::render('Roadmap');
    }

    public function faqs(){
        return Inertia::render('Faqs');
    }

    public function contact(){
        return Inertia::render('Contact');
    }

    public function getPromo(){
        if(Auth::check()){
            $user = Auth::user();
        }else{
            $user = "";
        }
        return view('frontend.pages.getPromo')->with('user', $user);
    }

    public function promoStore(Request $request){
        $data['user_id'] = Auth::id();
        $data['promo_code'] = Str::random(8); 

        $check = DB::table('promo_code')->where('user_id', $data['user_id'])->count();
        if($check == 0){
            $insert = DB::table('promo_code')->insert($data);
            if($insert){
                return back()->with('success', 'Promotion Code Created Successfully');
            }else{
                return back()->with('error', 'Something Went Wrong');
            }
        }else{
            return back()->with('error', 'User can only have 1 Promotion Code and you already have one!');
        }
    }

    public function applyPromo(Request $request){
        $this->validate($request, [
            'promo_code' => 'required'
        ]);
        $data = $request->all();
        $userPromo = DB::table('promo_code')->where(['user_id'=>Auth::id()])->first();
        if(!empty($userPromo) && $userPromo->promo_code == $data['promo_code']){
            return response()->json(['error' => 400, 'msg' => 'You cannot use your own Promotion Code']);
        }else{
            $existPromo = DB::table('promo_code')->where(['promo_code'=>$data['promo_code']])->first();
            if($existPromo){
                return response()->json(['success' => 200, 'msg' => 'Promotion Code Applied']);
            }else{
                return response()->json(['error' => 400, 'msg' => 'Promotion Code does not exist']);
            }
        }
    }

    public function nftMinted(Request $request){
        $data = $request->all();
        $minted = array(
            'user_id' => Auth::id(),
            'token_id' => $data['token_id'],
            'collection_address' => $data['collection_address'],
            'collection_name' => $data['collection_name'],
            'wallet_address' => $data['wallet_address'],
            'transaction_hash' => $data['transaction_hash'],
        );
        $insert = DB::table('nft_minted')->insert($minted);
        if($insert){
            $notification = 'Successfully Minted NFT# '. $data['token_id'];
            if(isset($data['promo_code']) && ($data['promo_code'] != '' || $data['promo_code'] != null) ){
                $promo_user = DB::table('promo_code')->where('promo_code', $data['promo_code'])->first();
                if(!empty($promo_user)){
                    $promo_used = array(
                        'user_id' => Auth::id(),
                        'promo_code' => $data['promo_code'],
                        'collection_address' => $data['collection_address'],
                        'collection_name' => $data['collection_name'],
                        'wallet_address' => $data['wallet_address'],
                        'token_id' => $data['token_id']   
                    );
                    $usedPromo = DB::table('promo_used')->insert($promo_used);
                    if($usedPromo){
                        $points = $promo_user->points + 10;
                        DB::table('promo_code')->where('promo_code', $data['promo_code'])->update(array('points' => $points ));
                        $notification .= ' & Successfully used Promotion Code '. $data['promo_code'];
                    }else{
                        $notification .= 'Unable to use Promotion Code '. $data['promo_code'];
                    }
                }
            }
            return response()->json(['success' => 200, 'msg' => $notification]);
        }else{
            return response()->json(['error' => 400, 'msg' => 'Something Went Wrong']);
        }
    }

    public function points(){
        if(Auth::check()){
            $user = Auth::user();
            $points = DB::table('promo_code')->where('user_id', $user->id)->first();
            $withdrawrequest = DB::table('withdrawrequest')->where('user_id', $user->id)->orderBy('id', 'desc')->get();
            $promo_used = DB::table('promo_used')->where('user_id', $user->id)->orderBy('id', 'desc')->get();
            
            return Inertia::render('Points',[
                'user' => $user,
                'points' => $points,
                'withdrawrequest' => $withdrawrequest,
                'promo_used' => $promo_used
            ]);
        }else{
            return back()->with('error', 'Login first to continue');
        }
    }

    public function withdrawRequest(Request $request){
        $user = Auth::user();
        $points = DB::table('promo_code')->where('user_id', $user->id)->first();
        $data = array(
            'user_id'=>$user->id,
            'points'=>$points->points,
            'transaction' => Str::random(32)
        );
        $insert = DB::table('withdrawrequest')->insert($data);
        if($insert){
            $points = DB::table('promo_code')->where('user_id', $user->id)->update(array('points'=>0));
            redirect()->to('/points'); 
        }
    }

    public function productGrids(){

        $banners=Banner::where('status','active')->limit(3)->orderBy('id','DESC')->get();
        // return $banner;
        $products=Product::where('status','active')->orderBy('id','DESC')->get();

        // return Inertia::render('');
        return view('frontend.pages.product-grids')
                ->with('product_lists',$products)
                ->with('banners',$banners);
    }

    public function allCollections(){
        $banners = Banner::where(['type'=>'collections', 'status'=>'active'])->first();
        $collections = NFT::where('status','active')->orderBy('id','DESC')->get();

        return Inertia::render('Collections', [
            'banners' => $banners,
            'collections' => $collections
        ]);
    }

    public function getcollectionBySlug(Request $request, $slug){
        $collection = NFT::where(['slug'=>$slug, 'status'=>'active'])->first();
        $products = Product::where('collection', $collection->id)->get();
        return Inertia::render('CollectionDetails',[
            'collectionDetails' => $collection,
            'products' => $products
        ]);
    }

    public function productDetail($slug){
        $product_detail= Product::getProductBySlug($slug);
        $colorsID = explode(',', $product_detail->color);
        $colors = Colors::whereIn('id', $colorsID)->get();

        $collection = NFT::where('id', $product_detail->collection)->first();
        $reviews = ProductReview::getAllProductReview($product_detail->id);
        // dd($productReviews);
        $sizeID = explode(',', $product_detail->size);
        $sizes = Size::whereIn('id', $sizeID)->get();
        // dd($product_detail);
        return Inertia::render('ProductDetails',[
            'ProductDetails' => $product_detail,
            'sizes' => $sizes,
            'colors' => $colors,
            'collection' => $collection,
            'reviews' => $reviews,
            'reviewAvg' => $rate=ceil($product_detail->getReview->avg('rate'))
        ]);
    }

    public function allNfts(){
        $banners = Banner::where(['type'=>'nfts', 'status'=>'active'])->first();
        $nfts = NFT::where('status','active')->orderBy('id','DESC')->get();

        return Inertia::render('Nfts', [
            'banners' => $banners,
            'nfts' => $nfts
        ]);
    }

    public function getnftBySlug(Request $request, $slug){
        $nft = NFT::where(['slug'=>$slug, 'status'=>'active'])->first();
        return Inertia::render('NftDetails',[
            'nft' => $nft
        ]);
    }

    public function verify(){
        $nftcollections = NFT::where('status','active')->orderBy('id','DESC')->get(['contract_address', 'contract_abi']);
        return Inertia::render('Verify',[
            'nftcollections' => $nftcollections,
        ]);
    }

    public function verifyUsage(Request $request){
        $data = $request->all();
        $nft = array(
            'token_id' => $data['tokenId'],
            'collection_address' => $data['contract_address']
        );
        $check = DB::table('ordernft')->where($nft)->count();
        if($check > 0){
            return response()->json(['status'=>400, 'msg'=>'NFT is already Used to Buy Products!']);
        }else{
            $checkNFT = NFT::where('contract_address', $data['contract_address'])->first();
            if($checkNFT){
                foreach(json_decode($checkNFT['prices']) as $prices){
                    if(intval($data['tokenId']) >= intval($prices->from) && intval($data['tokenId']) <= intval($prices->to)){
                            $type = $prices->type;
                    }
                };
                if($type == 'personal'){
                    $limit = $checkNFT['personal_limit'];
                }else if($type == 'company'){
                    $limit = $checkNFT['company_limit'];
                }
                $nftData = [
                    'contract_name' => $checkNFT['title'],
                    'contract_address' => $data['contract_address'],
                    'tokenId' => $data['tokenId'],
                    'image' => $data['token_img'],
                    'type'=>$type,
                    'nftSlug'=>$checkNFT['slug'],
                    'limit'=>$limit,
                ];
                return response()->json(['status'=>200, 'data'=>$nftData, 'msg'=>"NFT {$data['contract_name']}#{$data['tokenId']} Verified, You can Now Buy Products for Free!"]);
            }
            return response()->json(['status'=>400, 'msg'=>'Something Went Wrong!']);
        }
    }
  
    public function productSearch(Request $request){
        $recent_products=Product::where('status','active')->orderBy('id','DESC')->limit(3)->get();
        $products=Product::orwhere('title','like','%'.$request->search.'%')
                    ->orwhere('slug','like','%'.$request->search.'%')
                    ->orwhere('description','like','%'.$request->search.'%')
                    ->orwhere('summary','like','%'.$request->search.'%')
                    ->orwhere('price','like','%'.$request->search.'%')
                    ->orderBy('id','DESC')
                    ->paginate('9');
        return view('frontend.pages.product-grids')->with('products',$products)->with('recent_products',$recent_products);
    }

    public function productBrand(Request $request){
        $products=Brand::getProductByBrand($request->slug);
        $recent_products=Product::where('status','active')->orderBy('id','DESC')->limit(3)->get();
        if(request()->is('e-shop.loc/product-grids')){
            return view('frontend.pages.product-grids')->with('products',$products->products)->with('recent_products',$recent_products);
        }
        else{
            return view('frontend.pages.product-lists')->with('products',$products->products)->with('recent_products',$recent_products);
        }

    }
    public function productCat(Request $request){
        $products=Category::getProductByCat($request->slug);
        // return $request->slug;
        $recent_products=Product::where('status','active')->orderBy('id','DESC')->limit(3)->get();

        if(request()->is('e-shop.loc/product-grids')){
            return view('frontend.pages.product-grids')->with('products',$products->products)->with('recent_products',$recent_products);
        }
        else{
            return view('frontend.pages.product-lists')->with('products',$products->products)->with('recent_products',$recent_products);
        }

    }
    public function productSubCat(Request $request){
        $products=Category::getProductBySubCat($request->sub_slug);
        // return $products;
        $recent_products=Product::where('status','active')->orderBy('id','DESC')->limit(3)->get();

        if(request()->is('e-shop.loc/product-grids')){
            return view('frontend.pages.product-grids')->with('products',$products->sub_products)->with('recent_products',$recent_products);
        }
        else{
            return view('frontend.pages.product-lists')->with('products',$products->sub_products)->with('recent_products',$recent_products);
        }

    }

    // Login
    public function login(){
        if(!session()->has('url.intended')){
            session(['url.intended' => url()->previous()]);
        }else{
            Session::forget('url.intended');
            session(['url.intended' => url()->previous()]);
        }
        return Inertia::render('Login');
    }
    public function loginSubmit(Request $request){
        $data= $request->all();
        if(Auth::attempt(['email' => $data['email'], 'password' => $data['password'],'status'=>'active'])){
            Session::put('user',$data['email']);
            request()->session()->flash('success','Successfully login');
            return redirect(session()->get('url.intended'));
        }
        else{
            request()->session()->flash('error','Invalid email and password please try again!');
            return redirect()->back();
        }
    }

    public function logout(){
        if(!session()->has('url.intended')){
            session(['url.intended' => url()->previous()]);
        }else{
            Session::forget('url.intended');
            session(['url.intended' => url()->previous()]);
        }
        Session::forget('user');
        Auth::logout();
        request()->session()->flash('success','Logout successfully');
        return redirect(session()->get('url.intended'));
    }

    public function register(){
        return Inertia::render('Register');
    }
    public function registerSubmit(Request $request){
        // return $request->all();
        $this->validate($request,[
            'name'=>'string|required|min:2',
            'email'=>'string|required|unique:users,email',
            'password'=>'required|min:6|confirmed',
        ]);
        $data=$request->all();
        // dd($data);
        $check=$this->create($data);
        if($check){
            request()->session()->flash('success','Successfully registered');
            return redirect()->route('login.form');
        }
        else{
            request()->session()->flash('error','Please try again!');
            return back();
        }
    }
    public function create(array $data){
        return User::create([
            'name'=>$data['name'],
            'email'=>$data['email'],
            'password'=>Hash::make($data['password']),
            'status'=>'active'
            ]);
    }
    // Reset password
    public function showResetForm(){
        return view('auth.passwords.old-reset');
    }

    public function subscribe(Request $request){
        if(! Newsletter::isSubscribed($request->email)){
                Newsletter::subscribePending($request->email);
                if(Newsletter::lastActionSucceeded()){
                    request()->session()->flash('success','Subscribed! Please check your email');
                    return redirect()->route('home');
                }
                else{
                    Newsletter::getLastError();
                    return back()->with('error','Something went wrong! please try again');
                }
            }
            else{
                request()->session()->flash('error','Already Subscribed');
                return back();
            }
    }
    
}
