<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Traits\Autenticable;
use App\Models\Producto;
use App\Models\Bodega;
use DB;
use Logger;

class AjusteController extends Controller {
    use Autenticable;

    const GUIA_AJUSTE = 500;

    public function ingresarGuiaAjuste(Request $request)
    {
        $datos = $request->json()->all();
        $token = $request->header('token');

        $usuario = $this->valida_token($token);
        if (is_null($usuario)) {
            return $this->tokenInvalido();
        }

        foreach($datos as $item => $guia) {
            $respuestas = [];

            try{
                $this->validateArray($request, $guia, [
                    'Encabezado' => 'required|array',
                    'Encabezado.Fecha' => 'required|date|date_format:Y-m-d',
                    'Encabezado.Operacion' => 'required|integer|in:1,2',
                    'Encabezado.Bodega' => 'required|integer',
                    'Encabezado.TipoDocumento' => 'required_with:Encabezado.FolioDocumento,Encabezado.RutProveedor|integer', //tipo documento documento relacionado con el ajuste
                    'Encabezado.FolioDocumento' => 'required_with_all:Encabezado.TipoDocumento,Encabezado.RutProveedor|integer', //folio documento relacionado con el ajuste
                    'Encabezado.Observacion' => 'required',
                    'Encabezado.RutProveedor' => 'required_with_all:Encabezado.TipoDocumento,Encabezado.FolioDocumento|rut',

                    'Detalle' => 'required|array',
                    'Detalle.*.Codigo' => 'required',
                    'Detalle.*.Cantidad' => 'required|numeric',
                    'Detalle.*.Lote' => 'integer',
                    'Detalle.*.TipoDescuento' => 'required|integer|in:1,2',
                    'Detalle.*.ValorDescuento' => 'required|numeric',
                    'Detalle.*.FechaVencimiento' => 'date|date_format:Y-m-d',
                    'Detalle.*.Costo' => 'numeric',
                ]);
            }catch(Exception $e){
                $respuestas[$item] = (array) $e->getResponse()->getData();
                continue;
            }

            $folio = $this->obtenFolioGuia($usuario->rut_empresa);

            $bodega = Bodega::obtenBodega($guia['Encabezado']['Bodega'], $usuario->rut_empresa);
            if(is_null($bodega)){
                $respuestas[$item] = ['mensaje' => 'Bodega '.$guia['Encabezado']['Bodega'].' invalida.'];
                continue;
            }

            try{
                if(isset($guia['Encabezado']['TipoDocumento']) && isset($guia['Encabezado']['FolioDocumento'])) {
                    $ingreso = DB::table('compra_inv_relacion')
                        ->insert([
                            'RUT_EMPRESA' => $usuario->rut_empresa,
                            'TIPO' => self::GUIA_AJUSTE,
                            'FOLIO' => $folio,
                            'RUT_PROVEEDOR' => $guia['Encabezado']['RutProveedor'],
                            'FOLIO_RELACION' => $guia['Encabezado']['FolioDocumento'],
                            'TIPO_RELACION' => $guia['Encabezado']['TipoDocumento'],
                        ]);

                    if(!$ingreso){
                        $respuestas[$item] = ['mensaje' => 'No se pudo realizar ingreso en relacion inventario compra item #'.$item.'.'];
                        $this->rollback($usuario->rut_empresa, $folio);
                        continue;
                    }
                }

                foreach($guia['Detalle'] as $detalle){
                    $producto = Producto::obtenProducto($detalle['Codigo'], $usuario->rut_empresa);
                    if(is_null($producto)){
                        $respuestas[$item] = ['mensaje' => 'Producto '.$detalle['Codigo'].' invalido.'];
                        $this->rollback($usuario->rut_empresa, $folio);
                        continue;
                    }
                    $costo = !isset($detalle['Costo']) ? $producto->VALOR_PRODUCTO : $detalle['Costo'];

                    if($producto->INV_PRODUCTO != Producto::PACK) {
                        $id_detalle_inv_productos = $ingreso = DB::table('detalle_inv_productos')
                            ->insertGetId([
                                'CODIGO_PRODUCTO' => $producto->CODIGO_PRODUCTO,
                                'FECHA_INGRESO' => date('Y-m-d', time()),
                                'FECHA_MOV' => $guia['Encabezado']['Fecha'],
                                'TIPO_MOV' => $guia['Encabezado']['Operacion'],
                                'FECHA_DOC' => date('Y-m-d', time()),
                                'FOLIO_DOC' => self::GUIA_AJUSTE,
                                'N_DOC' => $folio,
                                'RUT_EMPRESA' => $usuario->rut_empresa,
                                'OBS' => isset($guia['Encabezado']['Observacion']) ? $guia['Encabezado']['Observacion'] : '',
                                'CANTIDAD_DOC' => $detalle['Cantidad'],
                                'VALOR_PRODUCTO' => $costo,
                                'ADICIONAL2_DETALLE_INV' => $costo,
                                'ID_BODEGA' => $guia['Encabezado']['Bodega'],
                                'CANTIDAD_INV' => $detalle['Cantidad'],
                                'CORRE_COMPRA' => 0,
                                'ADICIONAL1_DETALLE_INV' => $usuario->rut_usuario,
                            ]);
                    }
                    else {
                        $pack_producto = Producto::obtenPackProducto($detalle['Codigo'], $usuario->rut_empresa);
                        $id_detalle_inv_productos = $ingreso = DB::table('detalle_inv_productos')
                            ->insertGetId([
                                'CODIGO_PRODUCTO' => $pack_producto->PROD_ADIC,
                                'FECHA_INGRESO' => date('Y-m-d', time()),
                                'FECHA_MOV' => $guia['Encabezado']['Fecha'],
                                'TIPO_MOV' => $guia['Encabezado']['Operacion'],
                                'FECHA_DOC' => date('Y-m-d', time()),
                                'FOLIO_DOC' => self::GUIA_AJUSTE,
                                'N_DOC' => $folio,
                                'RUT_EMPRESA' => $usuario->rut_empresa,
                                'OBS' => isset($guia['Encabezado']['Observacion']) ? $guia['Encabezado']['Observacion'] : '',
                                'CANTIDAD_DOC' => $detalle['Cantidad'] * $pack_producto->CANTIDAD,
                                'VALOR_PRODUCTO' => $costo,
                                'ADICIONAL2_DETALLE_INV' => $costo,
                                'ID_BODEGA' => $guia['Encabezado']['Bodega'],
                                'CANTIDAD_INV' => $detalle['Cantidad'],
                                'CORRE_COMPRA' => 0,
                                'ADICIONAL1_DETALLE_INV' => $usuario->rut_usuario,
                            ]);
                    }
                    if(!$ingreso){
                        $respuestas[$item] = ['mensaje' => 'No se pudo realizar el ingreso de detalle de inventario.'];
                        $this->rollback($usuario->rut_empresa, $folio);
                        continue;
                    }

                    if(isset($detalle['Lote']) && isset($detalle['FechaVencimiento'])) {
                      $ingreso = DB::table('adicional_inventario')
                          ->insert([
                              'ID_GEN' => $id_detalle_inv_productos,
                              'LOTE' => $detalle['Lote'],
                              'F_VENCIMIENTO' => $detalle['FechaVencimiento'],
                          ]);
                      if(!$ingreso){
                          $respuestas[$item] = ['mensaje' => 'No se pudo realizar el ingreso de adicional de inventario.'];
                          $this->rollback($usuario->rut_empresa, $folio);
                          continue;
                      }
                    }

                    $descuento = Producto::calculaDescuento($costo, $detalle['TipoDescuento'], $detalle['ValorDescuento']);

                    $ingreso = DB::table('descuento_inv_productos')
                        ->insert([
                            'RUT_EMPRESA' => $usuario->rut_empresa,
                            'CODIGO_PRODUCTO' => $producto->CODIGO_PRODUCTO,
                            'FECHA_MOV' => $guia['Encabezado']['Fecha'],
                            'TIPO_DOC' => self::GUIA_AJUSTE,
                            'N_DOC' => $folio,
                            'TIPO_DESC' => $detalle['TipoDescuento'],
                            'VALOR_DESC' => $detalle['ValorDescuento'],
                            'DESCUENTO' => $descuento,
                        ]);
                    if(!$ingreso){
                        $respuestas[$item] = ['mensaje' => 'No se pudo realizar el ingreso de descuento inventario.'];
                        $this->rollback($usuario->rut_empresa, $folio);
                        continue;
                    }
                }
            } catch(Exception $e){
                $this->rollback($usuario->rut_empresa, $folio);
                $respuestas[$item] = ['mensaje' => 'Excepción al ingresar datos en item #'.$item.'.'];
                continue;
            }

            if(!isset($respuestas[$item])) {
                $respuestas[$item] = [
                  'mensaje' => 'Guia de Ajuste ingresada correctamente',
                  'folio' => $folio,
                ];
            }
        }

        Logger::log(
            $usuario->rut_empresa,
            $request->path(),
            $request->method(),
            $usuario->rut_usuario,
            json_encode(utf8_encode_recursivo((array)$request->all())),
            $respuestas,
            ENV('AMBIENTE_SII'),
            $request->ip()
        );

        return response()->json($respuestas);
    }

    protected function obtenFolioGuia($rut_empresa)
    {
        $folio = DB::table('detalle_inv_productos')
            ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
            ->where('FOLIO_DOC', '=', self::GUIA_AJUSTE)
            ->orderBy('N_DOC', 'desc')
            ->first();
        if(is_null($folio)) {
            return 1;
        }

        return $folio->N_DOC + 1;
    }

    protected function rollback($rut_empresa, $folio, $id_adicional_inventario = null)
    {
        DB::table('compra_inv_relacion')
            ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
            ->where('TIPO', '=', self::GUIA_AJUSTE)
            ->where('FOLIO', '=', $folio)
            ->delete();

        DB::table('detalle_inv_productos')
            ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
            ->where('FOLIO_DOC', '=', self::GUIA_AJUSTE)
            ->where('N_DOC', '=', $folio)
            ->delete();

        DB::table('detalle_inv_productos')
            ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
            ->where('FOLIO_DOC', '=', self::GUIA_AJUSTE)
            ->where('N_DOC', '=', $folio)
            ->delete();

        if(!is_null($id_adicional_inventario)){
            DB::table('adicional_inventario')
                ->where('ID_GEN', '=', $id_adicional_inventario)
                ->delete();
        }

        DB::table('descuento_inv_productos')
            ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
            ->where('TIPO_DOC', '=', self::GUIA_AJUSTE)
            ->where('N_DOC', '=', $folio)
            ->delete();
    }

        public function index(Request $request)
        {
            $datos = $request->json()->all();
            $token = $request->header('token');

            $usuario = $this->valida_token($token);
            if (is_null($usuario)) {
                return $this->tokenInvalido();
            }

            $guias = DB::table('detalle_inv_productos')
                ->whereRaw('RUT_EMPRESA = \''.$usuario->rut_empresa.'\'')
                ->where('FOLIO_DOC', '=', self::GUIA_AJUSTE)
                ->select(
                    'CODIGO_PRODUCTO as codigo_producto',
                    'FECHA_INGRESO as fecha_ingreso',
                    'FECHA_MOV as fecha_movimiento',
                    'TIPO_MOV as tipo_movimiento',
                    'FOLIO_DOC as tipo_documento',
                    'N_DOC as folio_documento',
                    'OBS as observacion',
                    'CANTIDAD_DOC as cantidad',
                    'VALOR_PRODUCTO as precio',
                    'ID_BODEGA as bodega',
                    'CANTIDAD_INV as cantidad_inventario',
                    'ADICIONAL1_DETALLE_INV as usuario'
                )->get();

            return response()->json((array)$guias);
        }

        public function indexAgrupado(Request $request)
        {
            $datos = $request->json()->all();
            $token = $request->header('token');

            $usuario = $this->valida_token($token);
            if (is_null($usuario)) {
                return $this->tokenInvalido();
            }

            $guias = DB::table('detalle_inv_productos')
                ->whereRaw('RUT_EMPRESA = \''.$usuario->rut_empresa.'\'')
                ->where('FOLIO_DOC', '=', self::GUIA_AJUSTE)
                ->select(
                    'FECHA_INGRESO as fecha_ingreso',
                    'TIPO_MOV as tipo_movimiento',
                    'N_DOC as folio_documento',
                    'OBS as observacion',
                    'ADICIONAL1_DETALLE_INV as usuario'
                )->groupBy('N_DOC')
                ->orderBy('N_DOC', 'DESC')
                ->get();

            return response()->json((array)$guias);
        }
}
