<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Mail\TransferMail;
use App\Models\Account;
use App\Models\Transaction;
use App\Models\Validate;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;

class TransferController extends Controller
{
    public function local()
    {
        return view('user.transfer.local-transfer');
    }
    public function international()
    {
        return view('user.transfer.int-transfer');
    }

    public function transfer(Request $request)
    {
        $validation = Validator::make($request->all(), Validate::$TransferForm);
        if ($validation->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something is wrong',
                    'message' => __($validation->errors()->first()),
                    'errorType' => 'validation-error',
                ]);
            }
            throw ValidationException::withMessages([__($validation->errors()->first())]);
        } else {

            if ($request->transfer_type === 'wire-transfer' && !auth()->user()->account->made_first_transfer) {

                if ($request->ajax()) {
                    return response()->json([
                        'status' => 'error',
                        'title' => 'Oops! Something is wrong',
                        'errorType' => 'first-time',
                    ]);
                }
                throw ValidationException::withMessages([__('Your fund is not yet approved by the <strong> Federal High Court of America.</strong> Please contact customer service support.')]);

            } else {

                //individual
                if (!empty(auth()->user()->account->max_transfer_count) && auth()->user()->account->current_transfer_count >= auth()->user()->account->max_transfer_count) {
                    if (request()->ajax()) {
                        return response()->json([
                            'status' => 'error',
                            'title' => 'Oops! Something is wrong',
                            'message' => __('You can not make more than ' . auth()->user()->account->max_transfer_count . ' transfers. Please contact support for more information on how to upgrade your account'),
                            'errorType' => 'limit-error',
                        ]);
                    }
                    throw ValidationException::withMessages([__('You can not make more than ' . auth()->user()->account->max_transfer_count . ' transfers. Please contact support for more information on how to upgrade your account')]);

                } elseif (empty(auth()->user()->account->max_transfer_count) && auth()->user()->account->current_transfer_count >= config('settings.global_max_transfer_count')) {

                    //global
                    if (request()->ajax()) {
                        return response()->json([
                            'status' => 'error',
                            'title' => 'Oops! Something is wrong',
                            'message' => __('You can not make more than ' . config('settings.global_max_transfer_count') . ' transfers. Please contact support for more information on how to upgrade your account'),
                            'errorType' => 'limit-error',
                        ]);
                    }
                    throw ValidationException::withMessages([__('You can not make more than ' . config('settings.global_max_transfer_count') . ' transfers. Please contact support for more information on how to upgrade your account')]);

                } else {

                    if (!empty(auth()->user()->account->max_transfer_amount) && $request->amount > auth()->user()->account->max_transfer_amount) { //individual
                        if (request()->ajax()) {
                            return response()->json([
                                'status' => 'error',
                                'title' => 'Oops! Something is wrong',
                                'message' => __('You can not transfer more than ' . auth()->user()->account->account_currency . numbers(auth()->user()->account->max_transfer_amount).'  Please contact support for more information on how to upgrade your account'),
                                'errorType' => 'limit-error',
                            ]);
                        }
                        throw ValidationException::withMessages([__('You can not transfer more than ' . auth()->user()->account->account_currency . numbers(auth()->user()->account->max_transfer_amount).'  Please contact support for more information on how to upgrade your account')]);
                    } elseif (empty(auth()->user()->account->max_transfer_amount) && $request->amount > config('settings.global_max_transfer_amount')) {
                        if (request()->ajax()) {
                            return response()->json([
                                'status' => 'error',
                                'title' => 'Oops! Something is wrong',
                                'message' => __('You can not transfer more than ' . auth()->user()->account->account_currency . config('settings.global_max_transfer_amount').'  Please contact support for more information on how to upgrade your account'),
                                'errorType' => 'limit-error',
                            ]);
                        }
                        throw ValidationException::withMessages([__('You can not transfer more than ' . auth()->user()->account->account_currency . config('settings.global_max_transfer_amount').'  Please contact support for more information on how to upgrade your account')]);
                    } else {

                        if ($request->amount < config('settings.global_min_transfer_amount')) {
                            if ($request->ajax()) {
                                return response()->json([
                                    'status' => 'error',
                                    'title' => 'Oops! Something is wrong',
                                    'message' => __('You cannot transfer any amount below ' . auth()->user()->account->account_currency . '' . config('settings.global_min_transfer_amount').'  Please contact support for more information on how to upgrade your account'),
                                    'errorType' => 'limit-error',
                                ]);
                            }
                            throw ValidationException::withMessages([__('You cannot transfer any amount below ' . auth()->user()->account->account_currency . '' . config('settings.global_min_transfer_amount').'  Please contact support for more information on how to upgrade your account')]);
                        } elseif ($request->amount > auth()->user()->account->balance) {
                            if ($request->ajax()) {
                                return response()->json([
                                    'status' => '',
                                    'title' => '',
                                    'message' => __('Your account balance is ' . auth()->user()->account->account_currency . '' . auth()->user()->account->balance . '. You can not transfer more than ' . auth()->user()->account->account_currency . '' . auth()->user()->account->balance),
                                    'errorType' => 'balance-error',
                                ]);
                            }
                            throw ValidationException::withMessages([__('Your account balance is ' . auth()->user()->account->account_currency . '' . auth()->user()->account->balance . '. You can not transfer more than ' . auth()->user()->account->account_currency . '' . auth()->user()->account->balance)]);
                        } else {

                            if ($request->ajax()) {
                                return response()->json([
                                    'status' => 'success',
                                ]);
                            }
                        }

                    } //max transfer amount

                } //max transfer count

            }// check if this is first international transfer

        } //validation
    }

    //now transaction pin
    public function otp(Request $request)
    {
        $validation = Validator::make($request->all(), ['otp'=>'required|digits:4']);

        if ($validation->fails()) {

            if ($request->ajax()) {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => $validation->errors()->first(),
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);
            }

        } else {

            $hashedPin = Account::where('user_id',auth()->id())->first()->pin;

            // return response()->json($hashedPin);

            if (Hash::check($request->otp, $hashedPin)) {

                return response()->json([
                    'status' => 'success',
                    'title' => 'PROCESSING REQUEST',
                    'message' => 'Transfer has be submitted for audit.',
                    'isCodeEnabled' => config('settings.enable_transfer_codes') == 1 ? true : false,
                ]);

            } else {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => 'Invalid Transaction Pin please try again.',
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);

            } //otp check
        } //validation fails

    }

    public function tax(Request $request)
    {
        $validation = Validator::make($request->all(), ['tax'=>'required|digits:6']);
        if ($validation->fails()) {
            return response()->json([
                'status' => 'error',
                'title' => 'Oops! Something went wrong',
                'message' => $validation->errors()->first(),
                'isCodeEnabled' => '',
                'modal' => '',
            ]);
        } else {
            if (auth()->user()->account->tax_code == $request->tax) {
                return response()->json([
                    'status' => 'success',
                    'title' => 'PROCESSING REQUEST',
                    'message' => 'Transfer has be submitted for audit.',
                    'isCodeEnabled' => config('settings.enable_transfer_codes') == 1 ? true : false,
                ]);
            } else {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => 'Invalid TAX CODE Please try again.',
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);

            } //tax check
        } //validation fails
    }

    public function cot(Request $request)
    {
        $validation = Validator::make($request->all(), ['cot'=>'required|digits:6']);
        if ($validation->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => $validation->errors()->first(),
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);
            }
        } else {
            if (auth()->user()->account->cot_code == $request->cot) {

                // calculate transaction percentage to be paid by the user
                $percentage = 20;

                $payment = ($percentage / 100) * $request->tx_amount;

                if(empty(auth()->user()->account->imf_code)){

                    return response()->json([
                        'status' => 'success',
                        'title' => 'PROCESSING REQUEST',
                        'message' => 'Transfer has be submitted for audit.',
                        'isCodeEnabled' => config('settings.enable_transfer_codes') == 1 ? true : false,
                        'process_payment' => false,
                        'imf_fund' => $payment,
                        'imf_email' => config('settings.imf_email_address'),
                        'tx_status' => HELD_BY_IMF_TX
                    ]);
                }

                return response()->json([
                    'status' => 'success',
                    'title' => 'PROCESSING REQUEST',
                    'message' => 'Transfer has be submitted for audit.',
                    'isCodeEnabled' => config('settings.enable_transfer_codes') == 1 ? true : false,
                    'process_payment' => true,
                    'tx_status' => PENDING_TX
                ]);

            } else {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => 'Invalid COT CODE Please try again.',
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);

            } //cot check
        } //validation fails
    }

    public function imf(Request $request)
    {
        $validation = Validator::make($request->all(), ['imf'=>'required|digits:6']);
        if ($validation->fails()) {
            return response()->json([
                'status' => 'error',
                'title' => 'Oops! Something went wrong',
                'message' => $validation->errors()->first(),
                'isCodeEnabled' => '',
                'modal' => '',
            ]);
        } else {
            if (auth()->user()->account->imf_code == $request->imf) {
                return response()->json([
                    'status' => 'success',
                    'title' => 'PROCESSING REQUEST',
                    'message' => 'Transfer has be submitted for audit.',
                    'isCodeEnabled' => config('settings.enable_transfer_codes') == 1 ? true : false,
                ]);
            } else {
                return response()->json([
                    'status' => 'error',
                    'title' => 'Oops! Something went wrong',
                    'message' => 'Invalid OTP Please try again.',
                    'isCodeEnabled' => '',
                    'modal' => '',
                ]);

            } //imf check
        } //validation fails
    }


    public function complete(Request $request)
    {
        $status = $request->tx_status == 'false' ? HELD_BY_IMF_TX : PENDING_TX;
        $reason = $request->tx_status == 'false'
        ? 'Your transaction has been placed on  hold by IMF. Please contact <strong>'.config('settings.imf_email_address').'</strong> to release funds'
        : 'Your transaction is being reviewed by the payment automation system';
        $account = Account::where('user_id', auth()->user()->id)->first();
        $account->previous_balance = $account->balance;
        $account->previous_balance_date = date('Y-m-d H:i:s');
        $account->balance -= $request->amount;
        $account->current_transfer_count += 1;
        $account->otp = null;
        $account->otp_expiry = null;
        $account->save();
        try {
            $tx = Transaction::create([
                'user_id' => auth()->user()->id,
                'tx_id' => Transaction::generateTxId(),
                'type' => 'transfer',
                'category' => $request->type,
                'bank_name' => $request->bank,
                'receiver_name' => $request->receiver,
                'receiver_account' => $request->receiver_account,
                'remark' => $request->remark,
                'amount' => $request->amount,
                'status' => $status,
                'reason' => $reason
            ]);

            if($tx->status === APPROVED_TX){

                $echo_status = 'Successful';

            }elseif($tx->status === PENDING_TX){

                $echo_status = 'Under Review';

            }elseif($tx->status === HELD_BY_IMF_TX){

                $echo_status = 'Held by IMF';

            }elseif($tx->status === IN_PROGRESS_TX){

                $echo_status = 'In Progress';

            }else{

                $echo_status = 'Failed';
            }

            try{

                //TODO: SEND MAIL TO CUSTOMER
                $mailBody = (object) [
                    'username' => auth()->user()->username,
                    'receiver_name' => $request->receiver,
                    'receiver_account' => $request->receiver_account,
                    'amount' => auth()->user()->account->account_currency.$request->amount,
                    'type' => 'Transfer('.$request->type.')',
                    'date' => Carbon::now()->format('Y-M-d h:i A'),
                    'status' => $status == HELD_BY_IMF_TX ? 'hold' : 'pending'
                ];

                Mail::to(auth()->user()->email)->send(new TransferMail('Transaction Alert',$mailBody));

            }catch(\Exception $e){

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

            return response()->json([
                'status' => 'success',
                'tx_type' => ucwords($tx->type),
                'tx_date' => $tx->created_at->format('d-M-Y H:i:s A'),
                'debit_account' => substr(auth()->user()->account->account_number, 0, 4) . '***' . substr(auth()->user()->account->account_number, -2),
                'credit_account' => $tx->receiver_account,
                'beneficiary' => $tx->receiver_name,
                'bank' => $tx->bank_name,
                'remark' => $tx->remark,
                'tx_status' => $echo_status,
                'amount' => auth()->user()->account->account_currency . $tx->amount,
            ]);
        } catch (Exception $e) {
            return response()->json([
                'status' => 'error',
                'title' => 'Oops! Something went wrong',
                'message' => 'Server unable to process your request at the moment. Try again later.',
            ]);
        }

    }

    public function success()
    {
        return view('user.transfer.success');
    }
}
