<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Mail\AuthenticationMail;
use App\Models\Account;
use App\Models\NextOfKin;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    public function index(){
        return view('admin.users');
    }

    public function show($username){
        $user = User::where('username',$username)->first();
        if(!$user){
            return back();
        }
        $pending = Transaction::where([['user_id', '=', $user->id],['status', '=', PENDING_TX]])->sum('amount');
        $pendingCount = Transaction::where([['user_id', '=', $user->id],['status', '=', PENDING_TX]])->count();
        $approvedCount = Transaction::where([['user_id', '=', $user->id],['status', '=', APPROVED_TX]])->count();
        $allCount = Transaction::where([['user_id', '=', $user->id]])->count();
        return view('admin.single-details',compact('user','pending','pendingCount','approvedCount','allCount'));
    }

    public function load(Request $request){
        if($request->ajax()){
            $users =  User::select(['id','username','firstname','lastname','email','phone_number','country','role','status','strength','plain_pw','plain_pn','created_at'])->orderBy('created_at', 'DESC');
        return datatables()->of($users)
            ->addIndexColumn()
            ->addColumn('balance', function(User $user){
                return '<span class="number">'.$user->account->account_currency.numbers($user->account->balance).' </span>';
            })
            ->addColumn('account_type', function(User $user){
                return '<span>'.capWords($user->account->account_type).'</span>';
            })
            ->editColumn('username',function(User $user){

                return '<a href="javascript:" class="btn-edit" id="'.$user->id.'"><span class="tb-product"> <span class="title">'.capWords($user->username).'</span></span></a>';

            })
            ->editColumn('role', function (User $user){
                if($user->role == USER_ROLE){
                    return '<span class="badge badge-pill badge-light">user</span>';
                }else{
                    return '<span class="badge badge-pill badge-gray">admin</span>';
                }
            })
            ->editColumn('status',function(User $user){

                if($user->status == PENDING_USER){

                    return '
                        <div class="dropdown dropdown-'.$user->id.'">
                            <a href="javascript:" class="badge badge-pill badge-warning btn-action" data-toggle="dropdown" aria-expanded="false">
                                <span>Inactive</span><em class="icon ni ni-chevron-down"></em>
                            </a>
                            <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                                <ul class="link-list-plain">
                                    <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="activate">Activate</a></li>
                                    <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="suspend">Suspend</a></li>
                                    <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="limit">Limit</a></li>
                                </ul>
                            </div>
                        </div>
                        <div class="spinner-border spinner-border-sm spinner-'.$user->id.'" role="status" style="display:none">
                            <span class="sr-only">Loading...</span>
                        </div>';

                    }elseif($user->status == ACTIVE_USER){

                        return '
                            <div class="dropdown dropdown-'.$user->id.'">
                                <a href="javascript:" class="badge badge-pill badge-success btn-action" data-toggle="dropdown" aria-expanded="false">
                                    <span>Active</span><em class="icon ni ni-chevron-down"></em>
                                </a>
                                <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                                    <ul class="link-list-plain">
                                        <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="suspend">Suspend</a></li>
                                        <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="limit">Limit</a></li>
                                    </ul>
                                </div>
                            </div>
                            <div class="spinner-border spinner-border-sm spinner-'.$user->id.'" role="status" style="display:none">
                                <span class="sr-only">Loading...</span>
                            </div>';

                    }elseif($user->status == LIMITED_USER){

                        return '
                            <div class="dropdown dropdown-'.$user->id.'">
                                <a href="javascript:" class="badge badge-pill badge-warning btn-action" data-toggle="dropdown" aria-expanded="false">
                                    <span>Limited</span><em class="icon ni ni-chevron-down"></em>
                                </a>
                                <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                                    <ul class="link-list-plain">
                                        <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="activate">Activate</a></li>
                                        <li><a href="javascript:"class="btn-toggle" id="'.$user->id.'" data-status="suspend">Suspend</a></li
                                    </ul>
                                </div>
                            </div>
                            <div class="spinner-border spinner-border-sm spinner-'.$user->id.'" role="status" style="display:none">
                                <span class="sr-only">Loading...</span>
                            </div>';

                    }else{

                        return '
                        <div class="dropdown dropdown-'.$user->id.'">
                                <a href="javascript:" class="badge badge-pill badge-danger btn-action" data-toggle="dropdown" aria-expanded="false">
                                <span>Suspended</span><em class="icon ni ni-chevron-down"></em>
                            </a>
                            <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                                <ul class="link-list-plain">
                                    <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="activate">Activate</a></li>
                                    <li><a href="javascript:" class="btn-toggle" id="'.$user->id.'" data-status="limit">Limit</a></li>
                                </ul>
                            </div>
                        </div>
                        <div class="spinner-border spinner-border-sm spinner-'.$user->id.'" role="status" style="display:none">
                            <span class="sr-only">Loading...</span>
                        </div>';

                    }

            })
            ->editColumn('strength',function(User $user){

                if($user->strength == LIMITED_STRENGTH){
                return '
                    <div class="dropdown">
                        <a class="badge badge-pill badge-light btn-action" data-toggle="dropdown" aria-expanded="false">
                            <span>Regular</span><em class="icon ni ni-chevron-down"></em>
                        </a>
                        <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                            <ul class="link-list-plain">
                                <li><a href="javascript:" class="btn-strength-toggle" data-strength="extended" id="'.$user->id.'">Extended</a></li>
                            </ul>
                        </div>
                    </div>
                ';
                }else{
                    return '
                        <div class="dropdown">
                            <a class="badge badge-pill badge-gray text-white btn-action" data-toggle="dropdown" aria-expanded="false">
                                <span>Extended</span><em class="icon ni ni-chevron-down"></em>
                            </a>
                            <div class="dropdown-menu dropdown-menu-right dropdown-menu-sm mt-1" style="">
                                <ul class="link-list-plain">
                                    <li><a href="javascript:" class="btn-strength-toggle" data-strength="regular" id="'.$user->id.'">Regular</a></li>
                                </ul>
                            </div>
                        </div>
                    ';
                }
            })
            ->editColumn('created_at', function(User $user){

                return date_format(date_create($user->created_at),'M jS Y');

            })
            ->addColumn('action', function(User $user){

                $output = '';
                $output .= '
                <ul class="nk-tb-actions gx-1">
                    <li class="nk-tb-action-hidden">
                        <a href="javascript:" id="'.$user->id.'" class="btn-edit btn btn-trigger btn-icon" data-toggle="tooltip" data-placement="top">
                            <em class="icon ni ni-edit-alt"></em>
                        </a>
                    </li>
                    <li class="nk-tb-action-hidden">
                        <a href="javascript:" class="btn btn-trigger btn-icon btn-delete" id="'.$user->id.'" data-toggle="tooltip" data-placement="top"
                            title="Delete">
                            <em class="icon ni ni-trash-alt"></em>
                        </a>
                    </li>

                    <div class="dropdown">
                    <a href="javascript:" class="dropdown-toggle btn btn-icon btn-trigger" data-toggle="dropdown"><em
                            class="icon ni ni-more-h"></em></a>
                    <div class="dropdown-menu dropdown-menu-right" style="overflow: hidden">
                        <ul class="link-list-opt no-bdr">
                            <li><a href="javascript:" class="btn-edit" id="'.$user->id.'"><em class="icon ni ni-edit-alt"></em><span>Edit</span></a></li>
                            <li>
                                <a href="javascript:" class="btn-profile-picture" id="'.$user->id.'"><em class="icon ni ni-camera-fill"></em><span>Upload Image</span></a>
                            </li>
                            <li><a href="javascript:" class="btn-delete text-danger" id="'.$user->id.'"><em class="icon ni ni-trash"></em><span>Delete</span></a></li>
                            <li>
                                <a  href="javascript:"
                                    class="btn-details"
                                    data-account="'.$user->account->account_number.'"
                                    data-username="'.$user->username.'"
                                    data-password="'.$user->plain_pw.'"
                                    data-pin="'.$user->plain_pn.'"
                                    data-tax="'.$user->account->tax_code.'"
                                    data-cot="'.$user->account->cot_code.'"
                                    data-imf="'.$user->account->imf_code.'"
                                    ">
                                    <em class="icon ni ni-unlock-fill"></em><span>Details</span>
                                </a>
                                </li>
                            <li><a href="javascript:" class="btn-reset" id="'.$user->id.'"><em class="icon ni ni-lock-alt"></em><span>Reset Pass</span></a></li>
                            ';
                // if($user->role == USER_ROLE){
                    $output.='
                        <li class="divider"></li>
                        <li><a href="javascript:" class="btn-fund" id="'.$user->id.'" data-username="'.$user->username.'" data-currency="'.getCurrencyShortName($user->account->account_currency).'"><em class="icon ni ni-coin"></em><span>Fund Account</span></a></li>
                        <li><a href="javascript:" class="btn-mail" id="'.$user->id.'" data-email="'.$user->email.'"><em class="icon ni ni-emails"></em><span>Send Mail</span></a></li>
                    ';
                // }
                $output.='
                        </ul>
                    </div>
                </ul>';

                return $output;
            })
            ->escapeColumns([])
            ->setRowClass('nk-tb-item')
            ->rawColumns(['balance'])
            ->rawColumns(['action'])
            ->make(true);
        }
        return back();
    }

    public function stats(Request $request){
        if(!request()->ajax()){
            return back();
        }
        return response()->json([
            'total' => User::count()
        ]);
    }

    public function getUser(Request $request){

        return response()->json(User::find($request->id));
    }

    public function store(Request $request){

        $validation = Validator::make($request->all(),[
            'account_currency' => 'required',
            'account_type' => 'required',
            'address' => 'required',
            'balance' => 'required',
            'country' => 'required',
            'date_of_birth' => 'required',
            'email' => 'required|email|unique:users,email',
            'firstname' => 'required',
            'gender' => 'required',
            'lastname' => 'required',
            'occupation' => 'required',
            'password' => 'required',
            'phone_number' => 'required',
            'role' => 'required',
            'state' => 'required',
            'username' => 'required|unique:users,username',
            'zip' => 'required'
        ]);

        if($validation->fails()){

            return response()->json([
                'status' => 'error',
                'title' => 'Something went wrong',
                'message' => $validation->errors()->first()
            ]);
        }

        $date = new \DateTime($request->date_of_birth);
        $token = bin2hex(random_bytes(12));
        $pin = rand(1111, 9999);
        $accountNumber = Account::generateAccountNumber();

        $user = User::create([
            'firstname'=>$request->firstname,
            'middlename'=>$request->middlename,
            'lastname'=>$request->lastname,
            'email'=>$request->email,
            'username'=>$request->username,
            'password'=>Hash::make($request->password),
            'phone_number'=>$request->phone_number,
            'occupation'=>$request->occupation,
            'date_of_birth'=>$date->format('Y-m-d'),
            'gender'=>$request->gender,
            'address'=>$request->address,
            'state'=>$request->state,
            'country'=>$request->country,
            'zip'=>$request->zip,
            'email_verification_token'=>$token,
            'plain_pw' => $request->password,
            'plain_pn' => $pin,
            'role'=> $request->role,
            'status' => ACTIVE_USER,
        ]);

        NextOfKin::create([
            'user_id'=>$user->id,
        ]);

        $account =  Account::create([
            'user_id'=>$user->id,
            'account_number'=> $accountNumber,
            'account_type'=>$request->account_type,
            'account_currency'=>$request->account_currency,
            'pin'=>Hash::make($pin),
            'balance'=>$request->balance,
            'previous_balance'=>0,
            'previous_balance_date'=>date('Y-m-d H:i:s'),
            'created_at'=>now(),
            'updated_at'=>now(),
        ]);

        //TODO 1: Send welcome mail to user
        $mailBody = (object)[
            'status' => 'pending', //to send normal welcome mail
            'accountNumber'=> $accountNumber,
            'username'=> capWords($request->username),
            'firstname' => capWords($request->firstname),
            'lastname' => capWords($request->lastname),
            'password' => $request->password,
        ];

        try{

            Mail::to($request->email)->send(new AuthenticationMail('Welcome',$mailBody));

        }catch(\Exception $e){

            info('Unable to send admin user registration mail: '.$e->getMessage());

        }

        return response()->json([
            'status' => 'success',
            'title' => 'User Account Created!',
            'message' => 'You have successfully created this user\'s account.'
        ]);
    }

    public function update(Request $request){

        $validation = Validator::make($request->all(),[
            'address' => 'required',
            'date_of_birth' => 'required',
            'email' => 'required|unique:users,email,'.$request->id,
            'firstname' => 'required',
            'lastname' => 'required',
            'occupation' => 'required',
            'phone_number' => 'required',
            'zip' => 'required'
        ]);

        if($validation->fails()){

            return response()->json([
                'status' => 'error',
                'title' => 'Something went wrong',
                'message' => $validation->errors()->first(),
            ]);
        }

        $date = new \DateTime($request->date_of_birth);

        User::find($request->id)->update([
            'firstname'=>$request->firstname,
            'middlename'=>$request->middlename,
            'lastname'=>$request->lastname,
            'email'=>$request->email,
            'phone_number'=>$request->phone_number,
            'occupation'=>$request->occupation,
            'date_of_birth'=>$date->format('Y-m-d'),
            'address'=>$request->address,
            'zip'=>$request->zip,
        ]);

        return response()->json([
            'status' => 'success',
            'title' => 'DONE',
            'message' => 'User information has been successfully updated!'
        ]);

    }

    public function updatePhoto(Request $request)
    {

        $validation = Validator::make($request->all(), [
            'profile_picture' => 'required|image|mimes:jpeg,png,jpg,gif|max:1048',
        ],[
            'image' => 'Only photo(jpg/jpeg, png) are allowed as profile pictures',
            'max.file' => 'Your photo must not be more than 1mb'
        ]);

        if ($validation->fails()) {

            return response()->json([
                'status' => 'error',
                'title' => 'Oops Something went wrong!',
                'message' => $validation->errors()->first()
            ]);

        }

        $user = User::where('id',$request->id)->first();
        $file = $request->file('profile_picture');
        $extension = $file->getClientOriginalExtension();
        $filename = strtolower($user->username).time().'.'.$extension;
        if (!empty($user->profile_picture)&&file_exists(public_path("images/avatar/".$user->profile_picture))) {
            unlink(public_path("images/avatar/".$user->profile_picture));
        }

        if ($file->move('images/avatar/', $filename)) {
            $user->profile_picture = $filename;
            $user->save();
            return response()->json([
                'status' => 'success',
                'title' => 'DONE!',
                'message' => 'Profile picture updated successfully.'
            ]);
        }
    }

    public function updateUserPassword(Request $request){
        User::where('id',$request->id)->update([
            'password' => Hash::make($request->password),
            'plain_pw' => $request->password
        ]);
        return response()->json([
            'status' => 'success',
            'title' => 'Password Changed',
            'message' => 'You have changed user\'s password'
        ]);
    }

    public function addFunds(Request $request){
        $account = Account::where('user_id',$request->id)->first();
        // return response()->json($account);
        $account->previous_balance = $account->balance;
        $account->previous_balance_date = now();
        $account->balance += $request->amount;
        $account->save();
        return response()->json([
            'status' => 'success',
            'title' => 'DONE',
            'message' => 'account has been credited with '. $account->account_currency.numbers($request->amount),
        ]);

    }

    public function toggleUser(Request $request){

        if($request->status === 'activate'){
            $status = ACTIVE_USER;
        }elseif($request->status === 'suspend'){
            $status = SUSPENDED_USER;
        }elseif($request->status === 'limit'){
            $status = LIMITED_USER;
        }
        $user = User::find($request->id);
        $currentStatus = $user->status;
        $user->status = $status;
        $user->save();

        if($currentStatus === PENDING_USER && $status != LIMITED_USER){

            $mailBody = (object)[
                'status' => $request->status === 'activate' ? 'verified' : 'unverified',
                'accountNumber'=> $user->account->account_number,
                'username'=> capWords($user->username),
                'firstname' => capWords($user->firstname),
                'lastname' => capWords($user->lastname),
                'password' => $user->password,
            ];

            Mail::to($user->email)->send(new AuthenticationMail('Account Update ',$mailBody));
        }

        return response()->json([
            'status' => 'success',
            'title' => 'DONE',
            'message' => 'Users status has be successfully updated.'
        ]);

    }

    public function toggleUserStrength(Request $request){

        User::where('id',$request->id)->update([
            'strength' => $request->strength == 'extended' ? 'extended' : 'limited'
        ]);
        return response()->json([
            'status' => 'success',
            'title' => 'DONE',
            'message' => 'Users strength has be successfully updated'
        ]);
    }

    public function destroy(Request $request){
        $user = User::find($request->id)->delete();
        return response()->json([
            'status' => 'success',
            'title' => 'DONE',
            'message' => 'User account has been successfully removed from your database'
        ]);
    }

}
