<?php
namespace App\Repositories;

use Illuminate\Support\Facades\DB;
use Exception;
use App\Models\ProductMovement;
use App\Models\WarehouseGuide;
use App\Models\WarehouseGuideDetail;
use App\Models\WarehouseGuideDetailSerie;
use App\Models\ProductDetails;
use App\Models\WarehouseStock;
use App\DTOs\WarehouseGuide\WarehouseGuideDetailCreateDto;
use App\DTOs\WarehouseGuide\WarehouseGuideDetailUpdateDto;
use App\Repositories\Interfaces\IWarehouseGuideDetailRepository;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class WarehouseGuideDetailRepository implements IWarehouseGuideDetailRepository
{
    public function paginate(array $request)
    {
        if ((isset($request['search'])) || (isset($request['orderby'])) || (isset($request['orderdir'])) || (isset($request['start'])) || (isset($request['length']))) {
            $orderBy = $request['orderby'];
            $orderDir = $request['orderdir'];
            $start = $request['start'];
            $length = $request['length'];

            if (isset($request['search'])) {
                $search = $request['search'];
    
                return WarehouseGuideDetail::orderBy($orderBy, $orderDir)
                    //->where('warehouse', 'like', '%'.$search.'%')
                    ->skip($start)
                    ->take($length)
                    ->get();
            } else {
                return WarehouseGuideDetail::orderBy($orderBy, $orderDir)
                    ->skip($start)
                    ->take($length)
                    ->get();
            }            
        } else {
            return WarehouseGuideDetail::get();
        }               
    }

    public function find(int $id): ?WarehouseGuideDetail
    {
        return WarehouseGuideDetail::find($id);
    }

    public function store($store): WarehouseGuideDetail
    {
        try{
            DB::connection('mysql_client')->beginTransaction();
            Log::debug("pasó por acá");
            $warehouseguide = WarehouseGuide::find($store->warehouseguide_id);
            if( !is_null($warehouseguide) ){
                $guide_type = $warehouseguide->guide_type;
                $entry = new WarehouseGuideDetail();
                $entry->warehouseguide_id = $store->warehouseguide_id;
                $entry->product_id = $store->product_id;
                $entry->name = $store->name;
                $entry->quantity = $store->quantity;
                $entry->price = $store->price;
                $entry->price_inc = $store->price_inc;
                $entry->total = $store->total;
                $entry->avgdiscount = $store->avgdiscount;
                $entry->lote = $store->lote;
                $entry->observation = $store->observation;
                $entry->production_date = (is_null($store->production_date) || $store->production_date == "" ? 
                    $store->production_date : 
                    Carbon::createFromFormat('d/m/Y', $store->production_date)->format('Y-m-d'));
                $entry->expiration_date = (is_null($store->expiration_date) || $store->expiration_date == "" ? 
                    $store->expiration_date : 
                    Carbon::createFromFormat('d/m/Y', $store->expiration_date)->format('Y-m-d'));
                
                if( $entry->save() ){
                    $entry_id = $entry->id;
                    $array_series = (is_null($store->series) || $store->series == "" 
                        ? [] 
                        : $store->series);
                    if( count($array_series) > 0 ){
                        foreach( $array_series as $serie ){
                            $warehouseguide_detail_serie = new WarehouseGuideDetailSerie();
                            $warehouseguide_detail_serie->warehouseguide_detail_id = $entry_id;
                            $warehouseguide_detail_serie->serie_number = $serie;
                            $warehouseguide_detail_serie->save();

                            $product_detail = new ProductDetails();
                            $product_detail->product_id = $store->product_id;
                            $product_detail->lote = $store->lote;
                            $product_detail->serie_number = $serie;
                            $product_detail->production_date = (is_null($store->production_date) || $store->production_date == "" ? 
                                "0000-00-00" :
                                Carbon::createFromFormat('d/m/Y', $store->production_date)->format('Y-m-d'));
                            $product_detail->expiration_date = (is_null($store->expiration_date) || $store->expiration_date == "" ? 
                                "0000-00-00" :
                                Carbon::createFromFormat('d/m/Y', $store->expiration_date)->format('Y-m-d'));
                            $product_detail->estado = 1;
                            $product_detail->warehouseguide_detail_in_id = ($guide_type == "I") ? $entry_id : "";
                            $product_detail->warehouseguide_detail_out_id = ($guide_type == "S") ? $entry_id : "";
                            $product_detail->save();
                        }
                    }
            
                    $current_datetime = Carbon::now();
                    $product_movement = new ProductMovement();
                    $product_movement->origin_id = 0;
                    $product_movement->local_id = $store->local_id;
                    $product_movement->warehouse_id = $warehouseguide->warehouse_id;
                    $product_movement->product_id = $store->product_id;
                    $product_movement->cant = $store->quantity;
                    $product_movement->tipo = $warehouseguide->guide_type;
                    $product_movement->idMotivo = $warehouseguide->movement_type_id;
                    $product_movement->ref = $warehouseguide->docreference_number;
                    $product_movement->uCrea = $store->userguide_id;
                    $product_movement->fCrea = $current_datetime->toDateTimeString();
                    $product_movement->uActualiza = "";
                    $product_movement->fActualiza = "";
                    $product_movement->estado = 1; //1
                    $product_movement->warehouseguide_detail_id = $entry_id;
                    
                    if( $product_movement->save() ){

                        $warehouse_stock = WarehouseStock::where('product_id', '=', $store->product_id)->first();
                        if( !is_null($warehouse_stock) && isset($warehouse_stock) ){
                            if( $guide_type == "I" ){
                                $warehouse_stock->stock = $warehouse_stock->stock + $store->quantity;
                            } elseif( $guide_type == "S" ){
                                $warehouse_stock->stock = $warehouse_stock->stock - $store->quantity;
                            }
                            $warehouse_stock->save();
                            Log::debug("Guardo bien la nueva entrada en stock");
                        }
                        DB::connection('mysql_client')->commit();
                        Log::debug("GUARDA BIEN EL MOVIMIENTO");
                    } else {
                        DB::connection('mysql_client')->rollBack();
                        Log::debug(json_encode($store));
                        Log::debug("ERROR AL GUARDAR EL MOVIMIENTO");
                    }
                }

                //user_create
                //local_id
                /*$current_datetime = Carbon::now();
                $product_movement = new ProductMovement();
                $product_movement->origin_id = 0;
                $product_movement->local_id = ;
                $product_movement->warehouse_id = ;
                $product_movement->product_id = $store->product_id;
                $product_movement->cant = $store->quantity;
                $product_movement->tipo = ;
                $product_movement->idMotivo = ;
                $product_movement->ref = ;
                $product_movement->uCrea = ;
                $product_movement->fCrea = $current_datetime->toDateTimeString();
                $product_movement->uActualiza = ;
                $product_movement->fActualiza = ;
                $product_movement->estado = 1; //1
                $product_movement->save();*/


            }
        } catch(\Exception $ex) {
            DB::connection('mysql_client')->rollback();
            Log::debug("ERROR AL GUARDAR: " . $ex->getMessage());
            Log::debug(json_encode($store));
        }

        return $entry;
    }

    public function update($store): void
    {
        try{
            DB::connection('mysql_client')->beginTransaction();
            $warehouseguide = WarehouseGuide::find($store->warehouseguide_id);
            if( !is_null($warehouseguide) ){
                $guide_type = $warehouseguide->guide_type;
                
                $entry = WarehouseGuideDetail::find($store->id);
                $entry->warehouseguide_id = $store->warehouseguide_id;
                $entry->product_id = $store->product_id;
                $entry->quantity = $store->quantity;
                $entry->price = $store->price;
                $entry->price_inc = $store->price_inc;
                $entry->total = $store->total;
                $entry->avgdiscount = $store->avgdiscount;
                $entry->lote = $store->lote;
                $entry->observation = $store->observation;
                $entry->production_date = (is_null($store->production_date) || $store->production_date == "" ? 
                    "0000-00-00" :
                    Carbon::createFromFormat('d/m/Y', $store->production_date)->format('Y-m-d'));
                $entry->expiration_date = (is_null($store->expiration_date) || $store->expiration_date == "" ? 
                    "0000-00-00" :
                    Carbon::createFromFormat('d/m/Y', $store->expiration_date)->format('Y-m-d'));
                Log::debug($entry->warehouseguide_id);
                Log::debug($entry->product_id);
                Log::debug($entry->quantity);
                Log::debug($entry->price);
                Log::debug($entry->price_inc);
                Log::debug($entry->total);
                Log::debug($entry->avgdiscount);
                Log::debug($entry->lote);
                Log::debug($entry->observation);
                Log::debug("FECHAS");
                Log::debug($store->production_date);
                Log::debug($store->expiration_date);
                Log::debug("ANTES DE GUARDAR");
                if( $entry->save() ){
                    $entry_id = $entry->id;
                    Log::debug("ENTRO");
                    $array_series = (is_null($store->series) || $store->series == "" 
                        ? [] 
                        : $store->series);

                    // borrar series
                    if( count($array_series) > 0 ){
                        foreach( $array_series as $serie ){
                            $warehouseguide_detail_serie = new WarehouseGuideDetailSerie();
                            $warehouseguide_detail_serie->warehouseguide_detail_id = $entry_id;
                            $warehouseguide_detail_serie->serie_number = $serie;
                            $warehouseguide_detail_serie->save();

                            $product_detail = new ProductDetails();
                            $product_detail->product_id = $store->product_id;
                            $product_detail->lote = $store->lote;
                            $product_detail->serie_number = $serie;
                            $product_detail->production_date = (is_null($store->production_date) || $store->production_date == "" ? 
                                $store->production_date : 
                                Carbon::createFromFormat('d/m/Y', $store->production_date)->format('Y-m-d'));
                            $product_detail->expiration_date = (is_null($store->expiration_date) || $store->expiration_date == "" ? 
                                $store->expiration_date : 
                                Carbon::createFromFormat('d/m/Y', $store->expiration_date)->format('Y-m-d'));
                            $product_detail->estado = 1;
                            $product_detail->warehouseguide_detail_in_id = ($guide_type == "I") ? $entry_id : "";
                            $product_detail->warehouseguide_detail_out_id = ($guide_type == "S") ? $entry_id : "";
                            $product_detail->save();
                        }
                    }
            
                    Log::debug("PASO SERIES");
                    $current_datetime = Carbon::now();
                    $product_movement = ProductMovement::where("warehouseguide_detail_id", '=', $entry_id)->first();
                    if( !is_null($product_movement) && isset($product_movement) ){
                        $stock_cant_old = $product_movement->cant;
                        $product_movement->origin_id = 0;
                        $product_movement->local_id = $store->local_id;
                        $product_movement->warehouse_id = $warehouseguide->warehouse_id;
                        $product_movement->product_id = $store->product_id;
                        $product_movement->cant = $store->quantity;
                        $product_movement->tipo = $warehouseguide->guide_type;
                        $product_movement->idMotivo = $warehouseguide->movement_type_id;
                        $product_movement->ref = $warehouseguide->docreference_number;
                        $product_movement->uCrea = "";
                        $product_movement->fCrea = "";
                        $product_movement->uActualiza = $store->userguide_id;
                        $product_movement->fActualiza = $current_datetime->toDateTimeString();
                        $product_movement->estado = 1; //1
                        $product_movement->warehouseguide_detail_id = $entry_id;
                        
                        if( $product_movement->save() ){

                            $warehouse_stock = WarehouseStock::where('product_id', '=', $store->product_id)->first();
                            if( !is_null($warehouse_stock) && isset($warehouse_stock) ){
                                if( $guide_type == "I" ){
                                    $warehouse_stock->stock = $warehouse_stock->stock - $stock_cant_old;
                                    $warehouse_stock->stock = $warehouse_stock->stock + $store->quantity;
                                } elseif( $guide_type == "S" ){
                                    Log::debug("Stock Actual: " . $warehouse_stock->stock);
                                    Log::debug("Cant. Ingreso Anterior: " . $stock_cant_old);
                                    $warehouse_stock->stock = $warehouse_stock->stock + $stock_cant_old;
                                    Log::debug("suma");
                                    Log::debug("Cant. Ingresada: " . $store->quantity);
                                    Log::debug("Stock Nuevo Calculado Suma: " . $warehouse_stock->stock);
                                    $warehouse_stock->stock = $warehouse_stock->stock - $store->quantity;
                                    Log::debug("resta");
                                    Log::debug("Stock Nuevo Calculado Resta: " . $warehouse_stock->stock);
                                }
                                $warehouse_stock->save();
                            }
                            DB::connection('mysql_client')->commit();
                        } else {
                            DB::connection('mysql_client')->rollBack();
                        }
                    }
                }
            }
        } catch(\Exception $ex) {
            Log::debug("ERROR: " . $ex->getMessage() . ", Linea: " . $ex->getLine());
            DB::connection('mysql_client')->rollback();
        }

    }

    public function destroy(int $id, $warehouseguide_typeguide): void
    {
        try{
            DB::connection('mysql_client')->beginTransaction();
            $warehouseguide_detail = WarehouseGuideDetail::find($id);
            $product_movement = $warehouseguide_detail->movement;
            $stock_cant_old = $product_movement->cant;
            $warehouse_stock = WarehouseStock::where('product_id', '=', $warehouseguide_detail->product_id)->first();
            if( !is_null($warehouse_stock) && isset($warehouse_stock) ){
                // calculo de forma contraria ya que hago un rollback de las operaciones, así vuelven a su estado anterior
                if( $warehouseguide_typeguide == "I" ){
                    $warehouse_stock->stock = $warehouse_stock->stock - $stock_cant_old;
                    $warehouseguide_detail->productDetailsIn()->delete();
                } elseif( $warehouseguide_typeguide == "S" ){
                    $warehouse_stock->stock = $warehouse_stock->stock + $stock_cant_old;
                    $warehouseguide_detail->productDetailsOut()->delete();
                }
                $warehouse_stock->save();
            }
            $warehouseguide_detail->movement()->delete();
            $series = $warehouseguide_detail->seriesDetalle()->delete();
            WarehouseGuideDetail::destroy($id);
            DB::connection('mysql_client')->commit();
            Log::debug('BORRADO');
        } catch(\Exception $ex) {
            DB::connection('mysql_client')->rollback();
            Log::debug('ERROR AL BORRAR: ' . $ex->getMessage());
        }
    }
}
