<?php

namespace App\Listeners\Gifts;

use App\Events\SalesGiftsEvent;

use App\Models\AssemblyProducts;
use App\Models\Coins;
use App\Models\ExpireDateQty;
use App\Models\FifoQty;
use App\Models\Journalizing;
use App\Models\Products;
use App\Models\ProductSales;
use App\Models\ProductSalesGifts;
use App\Models\ProductsQty;
use App\Models\ProductUnits;
use App\Models\SalesFifoQty;
use App\Models\SalesGifts;
use App\Models\StoreCountSales;
use App\Models\Stores;
use App\Models\StoresDefaultData;
use App\Models\Taxes;
use App\Services\Average;
use App\Traits\GeneralTrait;
use DB;
use DateTime;

class SalesGiftsListener
{
    use GeneralTrait;

    public function __construct()
    {
        //
    }

    public function handle(SalesGiftsEvent $event)
    {

        $average = new Average ;
        $ID=$event->ID;
        $def=StoresDefaultData::latest('id')->first();
        $Bill=SalesGifts::findOrFail($ID);
         $user=auth()->guard('admin')->user()->id;

        if(empty($event->requests['Safe'])){
            $event->requests['Safe']=null;
        }
        if(empty($event->requests['Status'])){
            $event->requests['Status']=1;
        }


        //Qty and Details

        if(!empty($event->requests['Unit'])){

            $P_Ar_Name=$event->requests['P_Ar_Name'];
            $P_En_Name=$event->requests['P_En_Name'];
            $Unit=$event->requests['Unit'];
            $P_Code=$event->requests['P_Code'];
            $Qty=$event->requests['Qty'];
            $AvQty=$event->requests['AvQty'];
            $Price=$event->requests['Price'];
            $Total=$event->requests['Total'];
            $Product=$event->requests['Product'];
            $VOne=$event->requests['VOne'];
            $VTwo=$event->requests['VTwo'];
            $V_Name=$event->requests['V_Name'];
            $VV_Name=$event->requests['VV_Name'];
            $Exp_Date=$event->requests['Exp_Date'];
            $CostPrice=$event->requests['CostPrice'];
            $TotCost=$event->requests['TotCost'];


            for($i=0 ; $i < count($Unit) ; $i++){

                $pp=ProductUnits::where('Product',$Product[$i])->where('Unit',$Unit[$i])->first();
                $plow=ProductUnits::where('Product',$Product[$i])->where('Rate',1)->first();
                $rr = ProductUnits::where("Unit",$Unit[$i])->where('Product',$Product[$i])->first();
                $prooooo=Products::find($Product[$i]);

                $uu['Product_Code']=$P_Code[$i];
                $uu['P_Ar_Name']=$P_Ar_Name[$i];
                $uu['P_En_Name']=$P_En_Name[$i];
                $uu['V_Name']=$V_Name[$i];
                $uu['VV_Name']=$VV_Name[$i];
                $uu['Qty']=$Qty[$i];
                $uu['AvQty']=$AvQty[$i];
                $uu['Price']=$Price[$i];
                $uu['Total']=$Total[$i];
                $uu['TotCost']=$TotCost[$i];
                $uu['Product']=$Product[$i];
                $uu['Unit']=$Unit[$i];
                $uu['Exp_Date']=$Exp_Date[$i];
                $uu['Gift']=$ID;
                $uu['V1']=$VOne[$i];
                $uu['V2']=$VTwo[$i];
                $uu['CostPrice']=$CostPrice[$i];
                $uu['Store']=$event->requests['Store'];
                ProductSalesGifts::create($uu);



                if($prooooo->P_Type == 'Assembly'){

                    $Asembs=AssemblyProducts::where('p_id',$Product[$i])->get();

                    foreach($Asembs as $ass){

                        $Quantity=$this->ProAvQties($event->requests['Store'],$ass->Product,$ass->P_Code);

                        if(!empty($Quantity)){

                            $prooooo=Products::find($ass->Product);
                            $unit=ProductUnits::where('Unit',$ass->Unit)->where('Product',$ass->Product)->first();
                            $plow=ProductUnits::where('Product',$ass->Product)->where('Rate',1)->first();
                            $pp=ProductUnits::where('Product',$ass->Product)->where('Unit',$ass->Unit)->first();

                            $qq= $unit->Rate * ($Qty[$i] * $ass->Qty) ;
                            $newqty=$Quantity->Qty -  $qq ;


                            if($newqty < 0){
                                return 5;
                            }



                            if($def->Cost_Price == 2){

                                $totCost=0;

                                $rr = ProductUnits::where("Unit",$ass->Unit)->where('Product',$ass->Product)->first();
                                $fifo=$this->FifoAvQtyDate($event->requests['Store'],$ass->Product,$ass->P_Code);

                                if(!empty($fifo)){

                                    if($fifo->Qty == 0){



                                        $NNQuntatity=$this->FindQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date);


                                        if($NNQuntatity == 0){


                                            $NNQuntatity=$this->FindQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date);


                                        }else{



                                            if($NNQuntatity >= ($Qty[$i] * $ass->Qty)){

                                                $totCost += $fifo->Cost_Price * $Qty[$i] ;

                                            }else{

                                                $res=($Qty[$i] * $ass->Qty) - $NNQuntatity ;


                                                $totCost += $fifo->Cost_Price * $NNQuntatity ;

                                                $ResdiualCost=$this->MoreThanQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date,$res);

                                                $totCost +=$ResdiualCost;

                                            }


                                        }



                                    }else{


                                        if($fifo->Qty >= ($Qty[$i] * $ass->Qty)){

                                            $totCost += $fifo->Cost_Price * ($Qty[$i] * $ass->Qty) ;

                                        }else{

                                            $res=($Qty[$i] * $ass->Qty) - $fifo->Qty ;


                                            $totCost += $fifo->Cost_Price * $fifo->Qty ;

                                            $ResdiualCost=$this->MoreThanQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date,$res);

                                            $totCost +=$ResdiualCost;

                                        }



                                    }


                                }

                                $newQQty= $unit->Rate * ($Qty[$i] * $ass->Qty) ;
                                $CostTotalSale=$totCost;

                                $in=0;
                                $out=$CostTotalSale;

                                $current=$newqty *  $totCost;




                                $cur= $totCost ;
                                $ty= $totCost / $newQQty;

                                if($event->requests['Status'] == 1) {
                                    ProductsQty::where('id', $Quantity->id)->update(['Qty' => $newqty, 'Price' => $ty, 'TotalCost' => $cur]);
                                }



                            }else{


                                $ty=$average->AverageCostGetUnit($ass->Product,$ass->P_Code,$event->requests['Store'],$ass->Unit);


                                $newQQty= $unit->Rate * $Qty[$i] ;
                                $CostTotalSale=$ty ;
                                $in=0;
                                $out=$CostTotalSale;


                                $current= $newqty  * ($ty / $unit->Rate) ;

                                $cur=$newqty * ($ty / $unit->Rate) ;
                                if($event->requests['Status'] == 1) {
                                    ProductsQty::where('id', $Quantity->id)->update(['Qty' => $newqty, 'Price' => $ty, 'TotalCost' => $cur]);
                                }

                            }

                            if($event->requests['Status'] == 1) {


                                //Products Moves
                                $move = [

                                    'Date' => $event->requests['Date'],
                                    'Type' => 'هدايا',
                                    'TypeEn' => 'Gifts',
                                    'Bill_Num' => $Bill->Code,
                                    'Incom' => 0,
                                    'Outcom' => $qq,
                                    'Current' => $newqty,
                                    'CostIn' => number_format((float)$in, 2, '.', ''),
                                    'CostOut' => number_format((float)$out, 2, '.', ''),
                                    'CostCurrent' => number_format((float)$current, 2, '.', ''),
                                    'P_Ar_Name' => $ass->P_Ar_Name,
                                    'P_En_Name' => $ass->P_En_Name,
                                    'P_Code' => $ass->P_Code,
                                    'Unit' => $ass->Unit,
                                    'Qty' => $Qty[$i] * $ass->Qty,
                                    'Group' => $prooooo->Group,
                                    'Store' => $event->requests['Store'],
                                    'Product' => $ass->Product,
                                    'V1' =>null,
                                    'V2' => null,
                                    'Brand' => $prooooo->Brand,
                                    'Safe' => null,
                                    'Branch' => null,
                                    'SalePrice' => $Price[$i],
                                    'ProductPrice' => $pp->Price,
                                    'Delegate' => null,
                                    'Payment_Method' => null,
                                    'User' => $user,

                                ];

                                $this->ProductMoves($move);


                            }

                        }


                        if($event->requests['Status'] == 1) {

                            //Expire Date
                            if (!empty($Exp_Date[$i])) {
                                $unit = ProductUnits::where('Unit', $ass->Unit)->where('Product', $ass->Product)->first();

                                $qq = $unit->Rate *( $Qty[$i] * $ass->Qty);


                                $EXPO = ExpireDateQty::find($Exp_Date[$i]);
                                $NewExpQty = $EXPO->Qty - $qq;

                                if($NewExpQty < 0){
                                    return 5;
                                }
                                ExpireDateQty::where('id', $Exp_Date[$i])->update(['Qty' => $NewExpQty]);


                            }

                            //Fifo
                            if ($def->Cost_Price == 2) {

                                $fifo=$this->FifoAvQtyDate($event->requests['Store'],$ass->Product, $ass->P_Code);


                                if (!empty($fifo)) {

                                    if ($fifo->Qty >= ($Qty[$i] * $ass->Qty)) {


                                        $unit = ProductUnits::where('Unit', $ass->Unit)->where('Product', $ass->Product)->first();

                                        $qq = $unit->Rate * ($Qty[$i] * $ass->Qty);

                                        $newqty = $fifo->Qty - $qq;

                                        if($newqty < 0){
                                            return 5;
                                        }
                                        FifoQty::where('id', $fifo->id)->update(['Qty' => $newqty]);


                                        $fifQty['Sales_Qty'] = ($Qty[$i] * $ass->Qty);
                                        $fifQty['Sales_ID'] = $ID;
                                        $fifQty['Fifo_ID'] = $fifo->id;
                                        $fifQty['Store'] = $fifo->Store;
                                        $fifQty['Product'] = $fifo->Product;
                                        $fifQty['Cost_Price'] = $fifo->Cost_Price;
                                        $fifQty['Purchases_Date'] = $fifo->Purchases_Date;

                                        SalesFifoQty::create($fifQty);


                                    } else {


                                        $resdiualQty = ($Qty[$i] * $ass->Qty) - $fifo->Qty;

                                        $unit = ProductUnits::where('Unit', $ass->Unit)->where('Product', $ass->Product)->first();

                                        $qq = $unit->Rate * ($fifo->Qty * $ass->Qty);

                                        $newqty = $fifo->Qty - $qq;

                                        if($newqty < 0){
                                            return 5;
                                        }

                                        FifoQty::where('id', $fifo->id)->update(['Qty' => $newqty]);


                                        $fifQty['Sales_Qty'] = $fifo->Qty;
                                        $fifQty['Sales_ID'] = $ID;
                                        $fifQty['Fifo_ID'] = $fifo->id;
                                        $fifQty['Store'] = $fifo->Store;
                                        $fifQty['Product'] = $fifo->Product;
                                        $fifQty['Cost_Price'] = $fifo->Cost_Price;
                                        $fifQty['Purchases_Date'] = $fifo->Purchases_Date;

                                        SalesFifoQty::create($fifQty);

                                        $ResdiualCost = $this->FifoStoreAssemblyQty($fifo->Store, $fifo->Product, $fifo->P_Code, $fifo->id, $fifo->Purchases_Date, $resdiualQty, $ass->Unit, $ass->Qty, $ID);


                                    }


                                }


                            }
                        }


                    }


                }elseif($prooooo->P_Type != 'Service' and $prooooo->P_Type != 'Subscribe'){

                    $Quantity=$this->ProAvQties($event->requests['Store'],$Product[$i],$P_Code[$i]);

                    if(!empty($Quantity)){
                        $unit=ProductUnits::where('Unit',$Unit[$i])->where('Product',$Product[$i])->first();

                        $qq= $unit->Rate * $Qty[$i] ;

                        $newqty=$Quantity->Qty -  $qq ;

                        if($newqty < 0){
                            return 5 ;
                        }



                        //Products Qties
                        if($def->Cost_Price == 2){
                            $totCost=0;

                            $fifo=$this->FifoAvQtyDate($event->requests['Store'],$Product[$i],$P_Code[$i]);

                            if(!empty($fifo)){

                                if($fifo->Qty == 0){

                                    $NNQuntatity=$this->FindQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date);


                                    if($NNQuntatity == 0){


                                        $NNQuntatity=$this->FindQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date);


                                    }else{



                                        if($NNQuntatity >= $Qty[$i]){

                                            $totCost += $fifo->Cost_Price * $Qty[$i] ;

                                        }else{

                                            $res=$Qty[$i] - $NNQuntatity ;


                                            $totCost += $fifo->Cost_Price * $NNQuntatity ;

                                            $ResdiualCost=$this->MoreThanQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date,$res);

                                            $totCost +=$ResdiualCost;

                                        }


                                    }



                                }else{


                                    if($fifo->Qty >= $Qty[$i]){

                                        $totCost += $fifo->Cost_Price * $Qty[$i] ;

                                    }else{

                                        $res=$Qty[$i] - $fifo->Qty ;


                                        $totCost += $fifo->Cost_Price * $fifo->Qty ;

                                        $ResdiualCost=$this->MoreThanQty($fifo->Store,$fifo->Product,$fifo->P_Code,$fifo->id,$fifo->Purchases_Date,$res);

                                        $totCost +=$ResdiualCost;

                                    }



                                }


                            }

                            $newQQty= $unit->Rate * $Qty[$i] ;
                            $CostTotalSale=$totCost;

                            $prooooo=Products::findOrFail($Product[$i]);



                            $in=0;
                            $out=$CostTotalSale;



                            $current=$newqty *  $totCost;


                            $cur= $totCost ;

                            $ty=$cur / $newQQty ;
                            if($event->requests['Status'] == 1) {
                                ProductsQty::where('id', $Quantity->id)->update(['Qty' => $newqty, 'Price' => $ty, 'TotalCost' => $cur]);
                            }



                        }else{


                            $newQQty= $unit->Rate * $Qty[$i] ;
                            $ty=$average->AverageCostGetUnit($Product[$i],$P_Code[$i],$event->requests['Store'],$Unit[$i]);
                            $CostTotalSale=$ty ;
                            $prooooo=Products::findOrFail($Product[$i]);
                            $in=0;
                            $out=$CostTotalSale;
                            $current= $newqty *  ($ty / $unit->Rate);
                            $cur=$newqty * ($ty / $unit->Rate) ;

                            if($event->requests['Status'] == 1) {
                                ProductsQty::where('id', $Quantity->id)->update(['Qty' => $newqty, 'Price' => $ty, 'TotalCost' => $cur]);
                            }
                        }



                        if($event->requests['Status'] == 1) {
                            //Products Moves
                            $move = [

                                'Date' => $event->requests['Date'],
                                'Type' => 'هدايا',
                                'TypeEn' => 'Gifts',
                                'Bill_Num' => $Bill->Code,
                                'Incom' => 0,
                                'Outcom' => $qq,
                                'Current' => $newqty,
                                'CostIn' => number_format((float)$in, 2, '.', ''),
                                'CostOut' => number_format((float)$out, 2, '.', ''),
                                'CostCurrent' => number_format((float)$current, 2, '.', ''),
                                'P_Ar_Name' => $P_Ar_Name[$i],
                                'P_En_Name' => $P_En_Name[$i],
                                'P_Code' => $P_Code[$i],
                                'Unit' => $Unit[$i],
                                'Qty' => $Qty[$i],
                                'Group' => $prooooo->Group,
                                'Store' => $event->requests['Store'],
                                'Product' => $Product[$i],
                                'V1' => $VOne[$i],
                                'V2' => $VTwo[$i],
                                'Brand' => $prooooo->Brand,
                                'Safe' => null,
                                'Branch' => null,
                                'SalePrice' => $Price[$i],
                                'ProductPrice' => $pp->Price,
                                'Delegate' => null,
                                'Payment_Method' => null,
                                'User' => $user,

                            ];

                            $this->ProductMoves($move);
                        }

                    }

                    if($event->requests['Status'] == 1) {
                        if (!empty($Exp_Date[$i])) {
                            $unit = ProductUnits::where('Unit', $Unit[$i])->where('Product', $Product[$i])->first();

                            $qq = $unit->Rate * $Qty[$i];



                            $EXPO = ExpireDateQty::find($Exp_Date[$i]);
                            $NewExpQty = $EXPO->Qty - $qq;


                            if($NewExpQty < 0){

                                return 5;
                            }


                            ExpireDateQty::where('id', $Exp_Date[$i])->update(['Qty' => $NewExpQty]);


                        }

                        //Fifo

                        if ($def->Cost_Price == 2) {

                            $fifo=$this->FifoAvQtyDate($event->requests['Store'],$Product[$i],$P_Code[$i]);


                            if (!empty($fifo)) {

                                if ($fifo->Qty >= $Qty[$i]) {


                                    $unit = ProductUnits::where('Unit', $Unit[$i])->where('Product', $Product[$i])->first();

                                    $qq = $unit->Rate * $Qty[$i];

                                    $newqty = $fifo->Qty - $qq;

                                    if($newqty < 0){
                                        return 5;
                                    }


                                    FifoQty::where('id', $fifo->id)->update(['Qty' => $newqty]);


                                    $fifQty['Sales_Qty'] = $Qty[$i];
                                    $fifQty['Sales_ID'] = $ID;
                                    $fifQty['Fifo_ID'] = $fifo->id;
                                    $fifQty['Store'] = $fifo->Store;
                                    $fifQty['Product'] = $fifo->Product;
                                    $fifQty['Cost_Price'] = $fifo->Cost_Price;
                                    $fifQty['Purchases_Date'] = $fifo->Purchases_Date;

                                    SalesFifoQty::create($fifQty);


                                } else {


                                    $resdiualQty = $Qty[$i] - $fifo->Qty;

                                    $unit = ProductUnits::where('Unit', $Unit[$i])->where('Product', $Product[$i])->first();

                                    $qq = $unit->Rate * $fifo->Qty;

                                    $newqty = $fifo->Qty - $qq;

                                    if($newqty < 0){
                                        return 5;
                                    }


                                    FifoQty::where('id', $fifo->id)->update(['Qty' => $newqty]);


                                    $fifQty['Sales_Qty'] = $fifo->Qty;
                                    $fifQty['Sales_ID'] = $ID;
                                    $fifQty['Fifo_ID'] = $fifo->id;
                                    $fifQty['Store'] = $fifo->Store;
                                    $fifQty['Product'] = $fifo->Product;
                                    $fifQty['Cost_Price'] = $fifo->Cost_Price;
                                    $fifQty['Purchases_Date'] = $fifo->Purchases_Date;

                                    SalesFifoQty::create($fifQty);


                                    $ResdiualCost = $this->FifoStoreQty($fifo->Store, $fifo->Product, $fifo->P_Code, $fifo->id, $fifo->Purchases_Date, $resdiualQty, $Unit[$i], $ID);


                                }


                            }


                        }

                    }



                }


            }
        }



        //Joun

        //Jounralizing
        $type_ar='مبيعات هدايا';
        $type_en='Sales Gifts';
        $debitor=$event->requests['Total_Cost'];
        $creditor=$event->requests['Total_Cost'];
        $account_cred=0;
        $account_debt=0;
        $date=$event->requests['Date'];
        $draw=$event->requests['Draw'];
        $coin=$event->requests['Coin'];
        $cost_center=null;
        $note=$event->requests['Note'];
        $total=$event->requests['Total_Cost'];
        $joun_id=0;
        $Code_Type=$Bill->Code;
        $Code=0;

        $data=[

            'type_ar'=>$type_ar,
            'type_en'=>$type_en,
            'code'=>$Code,
            'code_type'=>$Code_Type,
            'date'=>$date,
            'draw'=>$draw,
            'coin'=>$coin,
            'cost_center'=>$cost_center,
            'note'=>$note,
            'debitor_cred'=>0,
            'creditor_cred'=>$creditor,
            'account_cred'=>$account_cred,
            'debitor_debt'=>$debitor,
            'creditor_debt'=>0,
            'account_debt'=>$account_debt,
            'total'=>$total,
            'joun_id'=>$joun_id,
        ];

        $joun_id=$this->CreateNewJun($data);
        $new=Journalizing::findOrFail($joun_id);
        $data['code']=$new->Code;
        $data['joun_id']=$joun_id;

$newStore=Stores::findOrFail($event->requests['Store'])->Account;
        $data['creditor_cred'] = $event->requests['Total_Cost'];
        $data['account_cred'] =$newStore;
        $data['debitor_debt'] = $event->requests['Total_Cost'];
        $data['account_debt'] = $event->requests['Account'];
        $this->JunDetails($data);



    }







}
