<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\DTOs\Products\ProductCreateDto;
use App\DTOs\Products\ProductUpdateDto;
use App\Repositories\Interfaces\IProductRepository;
use Exception;
use App\Models\Product;
use App\Models\ComboItem;
use Symfony\Component\Console\Output\ConsoleOutput;

class ProductController extends Controller
{

    private $productRepository;
    
    private $errorConnection = "";

    public function __construct(Request $request, IProductRepository $productRepository)
    {        
        if (isset($request['business_information'])) {
            $business_information = $request['business_information'];
            $ruc = $business_information['ruc_number'];

            $existe_conexion = $this->setDBClient($ruc);

            if($existe_conexion['error']){
                $this->errorConnection=$existe_conexion['message'];
                return $this->messageError("Se espera un número de RUC válido.", 201); 
            } else {
                $this->productRepository = $productRepository;
            }
        } else {
            $this->errorConnection='Error en la conexión. Se espera número de RUC';
        }      
    }

    public function index(Request $request)
    {    
        if($this->errorConnection != ''){
            return $this->messageError($this->errorConnection, 201); 
        }

        $result = $this->productRepository->paginate($request->all());    

        if ($result) {
            return $this->successResponse($result, "Productos encontrados correctamente", 201);
        } else {
            return $this->errorResponse("No hay Productos", 201);
        }
        
    }

    public function show(int $id)
    {
        if($this->errorConnection != ''){
            return $this->messageError($this->errorConnection, 201); 
        }

        $result = $this->productRepository->find($id);

        if ($result) {
            $items = ComboItem::where('product_id', '=', $id)->get();
            $result['items'] = $items;

            return $this->successResponse($result, "Producto encontrado correctamente", 201);
        } else {
            return $this->errorResponse("Producto no encontrado", 201);
        }
    }

    public function store(Request $request)
    {        
        try {
            if($this->errorConnection != ''){
                return $this->messageError($this->errorConnection, 201); 
            }
    
            $code = $request['code'];
            $codeExist = Product::where('code', '=', $code)->get();

            if (count($codeExist) == 0) {
                $this->validate($request, [
                    'type' => 'required|max:20',
                    'name' => 'required|max:255',
                    'code' => 'required|max:50',
                    'short_name' => 'required|max:50',
                    'requires_lot_number' => 'required|max:1',
                    'requires_serial_number' => 'required|max:1',
                    'currency' => 'max:3',
                    'price' => 'required',
                    'image' => 'max:255',
                    'tax' => 'max:20',
                    'tax_method' => 'max:1',
                    'barcode_symbology' => 'required|max:20',
                    'custom_field_1' => 'max:250',
                    'custom_field_2' => 'max:250',
                    'custom_field_3' => 'max:250',
                    'presentation' => 'max:250'
                ], [
                    'type.required' => 'El tipo del Producto es requerido',
                    'code.required' => 'El código de Producto es requerido',
                    'code.max' => 'El código de Producto no puede superar los :max caracteres',
                    'name.required' => 'El nombre del Producto es requerido',
                    'short_name.required' => 'La nombre corto del Producto es requerido',
                    'requires_lot_number.required' => 'El requiere Numero de Lote del Producto es requerido',
                    'requires_serial_number.required' => 'El requiere Numero de Serie del Producto es requerido',
                    'price.required' => 'El precio del Producto es requerido',
                    'barcode_symbology.required' => 'La simbologia CodBar del Producto es requerido'
                ]);
    
                $store = new ProductCreateDto($request->except(array('business_information','items')));
                
                $result = $this->productRepository->store($store);

                if (isset($request['items'])) {
                    $items = $request['items'];
                    $total_items = count($items);
    
                    if ($total_items != 0) {
                        $product_id = $result['id'];
                           
                        foreach ($items as $item) {
                            $item_code = $item['item_code'];
                            $quantity = $item['quantity'];

                            $product_data = Product::where('code', '=', $item_code)->get();

                            $price = $product_data[0]->price;
                            $cost = $product_data[0]->cost;

                            $data = array(
                                'product_id'=>$product_id,
                                'item_code'=>$item_code,
                                'quantity'=>$quantity,
                                'price'=>$price,
                                'cost'=>$cost
                            );

                            ComboItem::insert($data);    
                        }
                    }
                }
                
                return $this->successResponse($result, "Producto creado correctamente", 201);
            } else {
                return $this->errorResponse("Codigo de Producto ingresado ya existe", 201);
            }
        } catch (\Illuminate\Validation\ValidationException $e) {
            return $this->errorResponse($e->response->original, 201);
        }        
    }

    public function update(int $id, Request $request)
    {
        try {
            if($this->errorConnection != ''){
                return $this->messageError($this->errorConnection, 201); 
            }
    
            $result = $this->productRepository->find($id);

            if ($result) {
                $code = $request['code'];
                $codeExist = Product::where('id', '!=', $id)->where('code', '=', $code)->get();
    
                if (count($codeExist) == 0) {
                    $this->validate($request, [
                        'code' => [
                            'required',
                            'max:50'
                        ],
                        'name' => 'required|max:255',
                        'short_name' => 'required|max:50',
                        'requires_lot_number' => 'required|max:1',
                        'requires_serial_number' => 'required|max:1',
                        'currency' => 'max:3',
                        'price' => 'required',
                        'image' => 'max:255',
                        'tax' => 'max:20',
                        'tax_method' => 'max:1',
                        'barcode_symbology' => 'required|max:20',
                        'type' => 'required|max:20',
                        'custom_field_1' => 'max:250',
                        'custom_field_2' => 'max:250',
                        'custom_field_3' => 'max:250',
                        'presentation' => 'max:250'
                    ], [
                        'code.required' => 'El código de Producto es requerido',
                        'code.max' => 'El código de Producto no puede superar los :max caracteres',
                        'name.required' => 'El nombre del Producto es requerido',
                        'short_name.required' => 'La nombre corto del Producto es requerido',
                        'requires_lot_number.required' => 'El requiere Numero de Lote del Producto es requerido',
                        'requires_serial_number.required' => 'El requiere Numero de Serie del Producto es requerido',
                        'price.required' => 'El precio del Producto es requerido',
                        'barcode_symbology.required' => 'La simbologia CodBar del Producto es requerido',
                        'type.required' => 'El tipo del Producto es requerido'
                    ]);
            
                    $data = $request->except(array('business_information','items'));
                    
                    $data['id'] = $id;
            
                    $entry = new ProductUpdateDto($data);
            
                    $this->productRepository->update($entry);

                    if (isset($request['items'])) {
                        $items = $request['items'];
                        $total_items = count($items);
        
                        if ($total_items != 0) {
                            ComboItem::where('product_id', '=', $id)->delete();

                            $product_id = $id;
                           
                            foreach ($items as $item) {
                                $item_code = $item['item_code'];
                                $quantity = $item['quantity'];

                                $product_data = Product::where('code', '=', $item_code)->get();
    
                                $price = $product_data[0]->price;
                                $cost = $product_data[0]->cost;
                                
                                $data = array(
                                    'product_id'=>$product_id,
                                    'item_code'=>$item_code,
                                    'quantity'=>$quantity,
                                    'price'=>$price,
                                    'cost'=>$cost
                                );
    
                                ComboItem::insert($data);      
                            }
                        }
                    }                    
                    
                    $result = $this->productRepository->find($id);
        
                    return $this->successResponse($result, "Producto actualizado correctamente", 201);
                } else {
                    return $this->errorResponse("Codigo de Producto ingresado ya existe", 201);
                }
            } else {
                return $this->errorResponse("Producto ingresado no existe", 201);
            }
        } catch (\Illuminate\Validation\ValidationException $e) {
            return $this->errorResponse($e->response->original, 201);
        }
    }

    public function destroy(int $id)
    {
        if($this->errorConnection != ''){
            return $this->messageError($this->errorConnection, 201); 
        }

        $result = $this->productRepository->find($id);

        if ($result) {
            ComboItem::where('product_id', '=', $id)->delete();
            
            $this->productRepository->destroy($id);

            return $this->successResponse($id, "Producto eliminado correctamente", 201);    
        } else {
            return $this->errorResponse("Producto ingresado no existe", 201);
        }
    } 
    // public function validarIdProducto(int $category_id)
    // {
    //     if($this->errorConnection != '') {
    //         return $this->messageError($this->errorConnection, 201)
    //     }
    //     $result = $this->productRepository->find($category_id);

    //     if($result) {
    //         ComboItem::where('category_id', '=', $id)->delete();
    //         $this->productRepository->destroy($category_id);
    //         return $this->successResponse($category_id, "No ha seleccionado categoria", 201)

    //     }else{
    //         return $this->errorResponse("Categoria Ingresado exiosamente");
    //     }
    // } 
    // public function ajax()
    // {
    //     $productRepository = productRepository::all();
    //     $
    // }  
}
