<?php

namespace App\Http\Controllers\Web;

use App\Helpers\LoopDetails;
use App\Http\Controllers\Controller;
use App\Http\Requests\LoopRequest;
use App\Invoice;
use App\Loop;
use App\LoopGroup;
use App\LoopGroupUser;
use App\LoopGroupUserPaid;
use App\Page;
use App\User;
use App\UserWallet;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class LoopChangeController extends Controller
{
    private $view = 'web.loops.';

    /**
     * Get the loop of the current month, if it dose not exist, create one
     */
    public function __construct(){
    }

    /**
     * Cancel form
     * display cancel fees details
     */

    public function cancel(Request $request)//: ?View|RedirectResponse
    {
        $data= $this->getData($request);
        // dd($data);
        if($data['redirect'] ?? ''){
            return redirect()->route($data['redirect']);
        }

        // DB::enableQueryLog(); // Enable query log
        $notes= Page::where('id', 4)->with(['descriptions'=> function ($q) {
            $q->where('language_id', currentLanguage()->id)->first();
        }])->first();
        // dd(DB::getQueryLog());
        $notes->description= $notes->descriptions->first()->toArray();
        $data['notes']= $notes->toArray();
        // dd($notes->toArray());

        $loopId= $request->loop_id;

        $route= route('loops.verify', ['loop_id'=> $loopId, 'type'=> 'cancel']);

        $data = $data + [
            'route'=> $route
        ];
        return view($this->view.'cancel', $data);
    }

    private static function getData($request)//: ?View|RedirectResponse
    {
        $loopId= $request->loop_id;

        // DB::enableQueryLog(); // Enable query log

        $query= Loop::where('loops.id', $loopId)
        ->select('loops.date as loop_date', 'loop_groups.*', 'loop_group_users.*', 'loop_group_users.id as loop_group_user_id')
        ->join('loop_groups', 'loop_groups.loop_id', '=', 'loops.id')
        ->join('loop_group_users', 'loop_groups.id', '=', 'loop_group_users.loop_group_id')
        ->where('loop_group_users.user_id',Auth::id())
        ->first();
        // dd(DB::getQueryLog());
        if( ! $query ) {
            return ['redirect'=> 'loops.index'];
        }

        $loopDetails= $query->toArray();
        // dd($loopDetails);

        $data= LoopDetails::loopUserInfo($loopDetails);

        if( $data['closed'] ) {
            return ['redirect'=> 'loops.index'];
        }

        $fees= settings('fees');
        $fees= $fees && json_decode($fees) ? json_decode($fees, true) : [];

        $warningDay= (int) $fees['warning_day'] ?? 0;
        $settingDelayFees= (float) $fees['delay_fees'] ?? 0;

        $withdrawFees= (float) $fees['withdraw_fees'] ?? 0;
        $delayFees= 0;

        if( count($data['unPaidMonths']) > 0 ) {
            // check if he missed current month share
            $delayFees= $data['loopDetails']['share'] * $settingDelayFees/100;
            if ($warningDay <= date('d')) {
                // fees on delay of all months
                $delayFees= ceil($delayFees * count($data['unPaidMonths']) );
            } else {
                // only fees on delay of previous months
                $delayFees= ceil($delayFees * (count($data['unPaidMonths']) - 1) );
            }
        }
        // Remaing amount should be paid
        // Encashment date is greater than today
        if (!$data['cashed']) {
            $remainingAmount= ceil($data['loopDetails']['share'] * count($data['unPaidMonths']));
        } else {
            $remainingAmount= ceil($data['loopDetails']['share'] * ($data['loopDetails']['period'] - count($data['paidMonth'])) );
        }

        $total= $remainingAmount + $withdrawFees + $delayFees;

        $data += [
            'remainingAmount'=> $remainingAmount,
            'withdrawFees'=> $withdrawFees,
            'delayFees'=> $delayFees,
            'total'=> $total
        ];
        // dd($route);
        // dd($data, $fees, $warningDay, $delayFees, $withdrawFees);
        return $data;
    }

    /**
     * Do cancel
     * This method called after the verfication process
     *
     * 1- check user got cashed or not
     *
     * 2- In case user get Cashed, then redirect him to pay wallet page , with the total he should pay,
     * and after he did that, cancel his subscribtion
     *
     * 3- Incase the user has not cashed yet, finish canellation process using `finishCancel` method
     */

    public static function doCancel($request)
    {
        // dd($request->code, $request->user()->phone, $request->loop_id);
        $data= self::getData($request);
        // dd($data);
        if($data['redirect'] ?? ''){
            return redirect()->route($data['redirect']);
        }

        if ($data['cashed']) {
            $paydata= [
                'user_id' => $request->user()->id,
                'amount' => $data['total'],
                'description' => sprintf(__('loops.withdraw_wallet_pay'), date('F Y', strtotime($data['loopDetails']['loop_date'])) ),
                'meta'=> [
                    'type'=> 'cancel',
                    'loop_id'=> $request->loop_id,
                    'loop_group_id'=> $data['loopDetails']['loop_group_id'],
                    'loop_group_user_id'=> $data['loopDetails']['loop_group_user_id'],
                    "remainingAmount" => $data['remainingAmount'],
                    "withdraw_fees" => $data['withdrawFees'],
                    "delay_fees" => $data['delayFees'],
                    "total" => $data['total']
                ]
            ];

            // dd($paydata);

            # REDIRECT TO WALLET PAGE TO PAY AMOUNT, AND FROM THERE CANCEL HIS SUBSCRIBTION
            session()->put('verfication_code', $request->code);
            session()->put('pay_data', $paydata);
            return redirect()->route('userswallet.pay', ['type'=> 'cancel']);
        }

        return self::finishCancel($request, $data);
        // return view('web.verification.success_verify', $data);
    }

    /**
     * Finish cancel process
     *
     * 1- Add total as a Debt amount, then cancel his subscribtion
     *
     * 2- Before canellation, add unpaid months to `loop_group_user_paids` table
     *
     * 3- Add invoice
     */
    public static function finishCancel (Request $request, Array $data= []) {

        if (!$data) {
            $data= self::getData($request);
        }
        // dd($data);
        if($data['redirect'] ?? ''){
            return redirect()->route($data['redirect']);
        }

        // 1- Cancel
        LoopGroupUser::where('id', $data['loopDetails']['loop_group_user_id'])
        ->update(['status'=> 'cancelled', 'cancelled_date'=> now()]);

        // 2- Add unpaid months
        // Insert unpaid in loop_group_user_paids

        $paidData= ['loop_group_user_id'=> $data['loopDetails']['loop_group_user_id'], 'created_at'=> now()];

        $months= $data['unPaidMonths'];

        if (!$data['cashed']) {
            $paidData['done'] = false;
        } else {
            $months= array_diff($data['loopMonths'], $data['paidMonth']);
            $paidData['done'] = true;
        }
        // dd($months);

        $allUnPaid= [];

        foreach ($months as $month) {
            $paidData['month']= $month;
            $allUnPaid[]= $paidData;
        }

        // dd($allUnPaid);
        LoopGroupUserPaid::insert($allUnPaid);

        // 2- Add amount to wallet
        $walletData= [
            'user_id' => $request->user()->id,
            'amount' => - $data['total'],
            'description' => sprintf(__('loops.withdraw_wallet'), date('F Y', strtotime($data['loopDetails']['loop_date'])) ),
            'meta'=> [
                'type'=> 'cancel',
                'loop_id'=> $request->loop_id,
                'loop_group_id'=> $data['loopDetails']['loop_group_id'],
                'loop_group_user_id'=> $data['loopDetails']['loop_group_user_id'],
                'period'=> $data['loopDetails']['period'],
                'months'=> count($months),
                "remainingAmount" => $data['remainingAmount'],
                "withdraw_fees" => $data['withdrawFees'],
                "delay_fees" => $data['delayFees'],
                "total" => $data['total']
            ]
        ];
        // dd($walletData);

        UserWallet::create($walletData);

        // 3- Create Invoice
        $invoiceData= [
            'code' => rand(10,99).time().rand(10,99),
            'loop_group_user_id'=> $data['loopDetails']['loop_group_user_id'],
            'meta' => [
                "type" => 'cancel',
                'loop_id'=> $request->loop_id,
                "remainingAmount" => $data['remainingAmount'],
                "withdraw_fees" => $data['withdrawFees'],
                "delay_fees" => $data['delayFees'],
                "total" => $data['total'],
            ]
        ];

        // dd($invoiceData);
        $invoice= Invoice::create($invoiceData);

        // dd($invoice->toArray());
        $data= $data + [
            // 'route'=> !$data['cashed']? route('loops.index') : null,
            'route'=> route('loops.index'),
            'success_notes' => !$data['cashed'] ?  __('loops.withdraw_uncashed_success') : __('loops.subscribe_success'),
            'invoice'=> $invoice->toArray()
        ];
        // dd($data);
        // return $data;
        return view('web.verification.success_verify', $data);

    }
}
