<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use App\Models\BusinessType;
use App\Models\ServiceCharge;
use App\Models\Floor;
use App\Models\Shop;
use App\Models\ShopBill;
use App\Models\ShopPayment;
use App\Models\BillGenerate;
use App\Models\User;
use App\Helpers\CurrentUser;
use App\Helpers\PaymentType;
use Carbon\Carbon;
use Auth;

class ShopDetailsController extends Controller
{
    //To get shop profile page...
    public function shopProfile($id)
    {
        //To fet userId..
        $userId = CurrentUser::getUserId();
        $singleShopData = Shop::where('id',$id)->with(['floorData','businessTypeData','serviceChargeData','shopOwnerData','shopKeeperData'])->first();
        $paymentTypeData = PaymentType::getPaymentTypeData();
        //To fetch business type & floor...
        $floorData = Floor::orderBy('floor_name', 'asc')->where('status', true)->where('user_id', $userId)->get();
        $businessTypeData = BusinessType::orderBy('type_name', 'asc')->where('status', true)->where('user_id', $userId)->get();
        $serviceChargeData = ServiceCharge::orderBy('id', 'asc')->where('status', true)->where('user_id', $userId)->get();
        $shopOwnerData = User::orderBy('name', 'asc')->where('status', true)->whereNotIn('role',['superadmin','admin'])->get();
        $shopKeeperData = User::orderBy('name', 'asc')->where('status', true)->whereNotIn('role',['superadmin','admin'])->get();

        //To get shop bill data...
        $shopBillData = ShopBill::orderBy('id', 'desc')->where('shop_id', $id)->paginate(10);
        $allShopBillCount = ShopBill::orderBy('id', 'desc')->where('shop_id', $id)->count();

        //Shop Due Payment Section...
        $dueInvoiceData = ShopPayment::orderBy('id', 'desc')->where('shop_id', $id)->paginate(10);
        $dueInvoiceCount = ShopPayment::orderBy('id', 'desc')->where('shop_id', $id)->count();

        //To get total paid,change & due amount...
        $totalNetPrice = ShopBill::whereIn('shop_id', [$id])->sum('net_amount');
        $totalPaidPrice = ShopBill::whereIn('shop_id', [$id])->sum('paid_amount');
        $totalDuePrice = ShopBill::whereIn('shop_id', [$id])->sum('due_amount');
        $totalChangePrice = ShopBill::whereIn('shop_id', [$id])->sum('change_amount');

        if(!empty($singleShopData)){
            // Check user has permission...
            if (auth()->user()->hasPermissionTo('shop-list', 'web')){
                return response()->json([
                    'message'   =>  'Successfully loaded ata.',
                    'singleShopData'   =>  $singleShopData,
                    'paymentTypeData'   =>  $paymentTypeData,
                    'floorData'   =>  $floorData,
                    'businessTypeData'   =>  $businessTypeData,
                    'serviceChargeData'   =>  $serviceChargeData,
                    'shopOwnerData'   =>  $shopOwnerData,
                    'shopKeeperData'   =>  $shopKeeperData,
                    'shopBillData'   =>  $shopBillData,
                    'allShopBillCount'   =>  $allShopBillCount,
                    'dueInvoiceData'   =>  $dueInvoiceData,
                    'dueInvoiceCount'   =>  $dueInvoiceCount,
                    'totalNetPrice'   =>  $totalNetPrice,
                    'totalPaidPrice'   =>  $totalPaidPrice,
                    'totalDuePrice'   =>  $totalDuePrice,
                    'status_code'   => 201
                ], 201);
            }else{
                return response()->json([
                    'message'   =>  'Oops! Access Denied.',
                    'status_code'   => 403
                ], 403);
            }
        }else{
            return response()->json([
				'message'   =>  'Sorry,You have no data.',
                'status_code'   => 500
			], 500);
        }
    }

    //To add due billing payment shop wise....
    public function addDueBillPaymentShopWise(Request $request)
    {
        $request->validate([
            'shop_id'=> 'required',
            'payment_method'=> 'required',
            'paid_amount'=> 'required',
            'payment_note'=> 'nullable',
        ]);

        $data = $request->all();
        //To get single bill payment data...
        $shopId = $request->shop_id;
        $paymentNote = $request->payment_note;
        $paymentMethod = $request->payment_method;
        $paidAmount = $request->paid_amount;
        $totalInputPaidAmount = $paidAmount;
        //To get all the ShopBill data with shop wise...
        $getAllShopBillIds = ShopBill::orderBy('id','asc')->where('status', true)->where('is_pay', false)
                            ->where('shop_id', $shopId)->select('id')->pluck('id')->toArray();
       
        $initialPaidAmount = 0;
        $billGenerateId = null;
        foreach($getAllShopBillIds as $key=>$singleBillingId){
            if(isset($singleBillingId) && $singleBillingId != null){
                //To get single shop bill data...
                $singleBillPaymentData = ShopBill::where('id', $singleBillingId)->first();


                //To calculate...
                $totalAmount = $singleBillPaymentData->net_amount;
                $totalDueAmount = $singleBillPaymentData->due_amount;
            
                //To check paid & due amount with paid amount...
                $initialPaidAmount += $paidAmount;
                $finalAmount = $totalDueAmount - $initialPaidAmount;
                if($finalAmount >= 0){
                    if($finalAmount == 0){
                        $subTotalPaidAmount = $singleBillPaymentData->paid_amount+$initialPaidAmount;
                        $singleBillPaymentData->paid_amount = $subTotalPaidAmount;
                        $singleBillPaymentData->due_amount = $finalAmount;
                        $singleBillPaymentData->is_pay = true;
                        $singleBillPaymentData->save();

                        //To define current paid amount...
                        $currentPaidAmount = $initialPaidAmount;

                        if($singleBillPaymentData->save()){
                            //To add new due shop payment & bill generate data...
                            $this->updateBillGenerateCalculation($singleBillPaymentData->bill_generate_id, $currentPaidAmount);
                            $this->addNewDueShopPayment($singleBillingId, $paymentMethod, $singleBillPaymentData, $currentPaidAmount, $paymentNote);

                            return response()->json([
                                'message'   =>  'Invoice payment added successfully.',
                                'status_code'   => 201
                            ], 201);
                        }else{
                            return response()->json([
                                'message'   =>  'Sorry, Something is wrong.!',
                                'status_code'   => 500
                            ], 500);
                        }
                    }else{
                        $subTotalPaidAmount = $singleBillPaymentData->paid_amount+$initialPaidAmount;
                        $singleBillPaymentData->paid_amount = $subTotalPaidAmount;
                        $singleBillPaymentData->due_amount = $finalAmount;
                        //To define current paid amount...
                        $currentPaidAmount = $initialPaidAmount;

                        if($singleBillPaymentData->save()){
                            //To add new due shop payment & bill generate data...
                            $this->updateBillGenerateCalculation($singleBillPaymentData->bill_generate_id, $currentPaidAmount);
                            $this->addNewDueShopPayment($singleBillingId, $paymentMethod, $singleBillPaymentData, $currentPaidAmount, $paymentNote);
                            
                            return response()->json([
                                'message'   =>  'Invoice payment added successfully.',
                                'status_code'   => 201
                            ], 201);
                        }else{
                            return response()->json([
                                'message'   =>  'Sorry, Something is wrong.!',
                                'status_code'   => 500
                            ], 500);
                        }
                    }
                }else{
                    //To define current paid amount...
                    $currentPaidAmount = $singleBillPaymentData->due_amount;

                    $singleBillPaymentData->paid_amount = $singleBillPaymentData->net_amount;
                    $singleBillPaymentData->change_amount = 0;
                    $singleBillPaymentData->due_amount = 0;
                    $singleBillPaymentData->is_pay = true;
                    if($singleBillPaymentData->save()){
                        //To add new due shop payment & bill generate data...
                        $this->updateBillGenerateCalculation($singleBillPaymentData->bill_generate_id, $currentPaidAmount);
                        $this->addNewDueShopPayment($singleBillingId, $paymentMethod, $singleBillPaymentData, $currentPaidAmount, $paymentNote);
                    }else{
                        return response()->json([
                            'message'   =>  'Sorry, Something is wrong.!',
                            'status_code'   => 500
                        ], 500);
                    }

                    //To update form paid amount...
                    $extraAmount = (-1)*$finalAmount;
                    $paidAmount = $extraAmount;
                    $initialPaidAmount = 0;
                }
            }else{
                return response()->json([
                    'message'   =>  'Sorry, You have no unpaid invoice.!',
                    'status_code'   => 500
                ], 500);
            }
        }

        return response()->json([
            'message'   =>  'Invoice payment added successfully.',
            'status_code'   => 201
        ], 201);
    }

    //To add new shop due bill payment data...
    public function addNewDueShopPayment($singleShopBillId, $paymentMethod, $singleShopBillData, $currentPaidAmount, $paymentNote)
    {
        $duePayData = new ShopPayment();
        $duePayData->user_id = $singleShopBillData->user_id;
        $duePayData->bill_generate_id = $singleShopBillData->bill_generate_id;
        $duePayData->shop_bill_id = $singleShopBillId;
        $duePayData->shop_id = $singleShopBillData->shop_id;
        $duePayData->paid_amount = $currentPaidAmount;
        $duePayData->payment_note = $paymentNote;
        $duePayData->paid_by = Auth::user()->name;
        $duePayData->paid_year = Carbon::now()->year;
        $duePayData->paid_month = date('F', strtotime(Carbon::now()));
        $duePayData->paid_date = Carbon::now()->today()->toDateString();
        $duePayData->payment_method = $paymentMethod;
        $duePayData->save();
    }

    //To update shop bill generate...
    private function updateBillGenerateCalculation($id, $paidAmount)
    {
        $singleBGD = BillGenerate::where('id', $id)->first();
        //To check paid amount with due amount...
        $totalPaidAmount = $singleBGD->paid_amount + $paidAmount;
        $finalAmount = $singleBGD->due_amount - $paidAmount;
        if($finalAmount >= 0){
            if($finalAmount == 0){
                $singleBGD->is_full_pay = true;
            }

            $singleBGD->paid_amount = $totalPaidAmount;
            $singleBGD->due_amount = $finalAmount;
            $singleBGD->save();
        }else{
            $singleBGD->paid_amount = $singleBGD->net_amount;
            $singleBGD->due_amount = 0;
            $singleBGD->is_full_pay = true;
            $singleBGD->save();
        }
    }

    //To get shop due payment invoice...
    public function getShopDuePaymentInvoice($shopInvoiceId)
    {
        //To get single shop due payment data...
        $singleShopPD = ShopPayment::where('id', $shopInvoiceId)->with(['shopData'])->first();
        $singleShopBillData = ShopBill::where('id',$singleShopPD->shop_bill_id)->first();
        $referencePaidAmount = $singleShopBillData->paid_amount - $singleShopPD->paid_amount;
        $referenceDueAmount = $singleShopBillData->net_amount - $referencePaidAmount;
        $unpaidBillingData = array(
            'id' => $singleShopBillData->id,
            'net_amount' => $singleShopBillData->net_amount,
            'paid_amount' => $referencePaidAmount,
            'due_amount' => $referenceDueAmount,
        );

        //Total price, discount, qty & grand total price...
        $subTotalDueAmount = $referenceDueAmount;
        $subTotalPaidAmount = $singleShopPD->paid_amount;
        $subaTotalCurrentDueAmount = $subTotalDueAmount - $subTotalPaidAmount;

        if(!empty($singleShopPD)){
            // Check user has permission...
            if (auth()->user()->hasPermissionTo('shop-list', 'web')){
                return response()->json([
                    'message'   =>  'Successfully loaded data.',
                    'singleShopPaymentData'   =>  $singleShopPD,
                    'unpaidBillingData'   =>  $unpaidBillingData,
                    'referenceDueAmount'   =>  $referenceDueAmount,
                    'subTotalPaidAmount'   =>  $subTotalPaidAmount,
                    'subTotalDueAmount'   =>  $subTotalDueAmount,
                    'subaTotalCurrentDueAmount'   =>  $subaTotalCurrentDueAmount,
                    'status_code'   => 201
                ], 201);
            }else{
                return response()->json([
                    'message'   =>  'Oops! Access Denied.',
                    'status_code'   => 403
                ], 403);
            }
        }else{
            return response()->json([
				'message'   =>  'Sorry you have no data.',
                'status_code'   => 500
			], 500);
        }
    }
}