<?php

namespace App\Http\Controllers;

use App\Http\Controllers\ResponseController;
use App\Http\Controllers\EncryptionController;
use App\Http\Controllers\ResourcesController;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class IssueTrackingController extends Controller
{
    private $responseController;
    private $encController;
    private $resourcesController;

    public function __construct(){
        $this->responseController = new ResponseController();
        $this->encController = new EncryptionController();
        $this->resourcesController = new ResourcesController();
    }

    public function reportProblem(Request $request) {
        $validator = Validator::make($request->all(),[
            'ORDER' => 'required|string',
            'TIPO' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'NOMBRE_EVIDENCIA1' => 'required|string',
            'EVIDENCIA1' => 'required|string',
            'NOMBRE_EVIDENCIA2' => 'string',
            'EVIDENCIA2' => 'string',
            'USUARIO' => 'required|string',
            'NUMERO_LINEA' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_ISSUE_TRACKING_REG000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $requestData = $request->all();
        
        // Se obtiene el usuario encriptado
        try {
            $user = $this->encController->decrypt($requestData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG001: Ocurrió un error al obtener el usuario.", [], 500);
        }

        // Se obtiene el número de orden enctriptado
        try {
            $orderNumber = $this->encController->decrypt($requestData['ORDER']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG002: Ocurrió un error al obtener el usuario.", [], 500);
        }


        try {
            $validateExists = DB::table('S002V01TORCO')->where('ORCO_NUOR', '=', $orderNumber)->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG003: Ocurrió un error al validar el número de orden de compra.", [], 500);
        }

        if (!$validateExists) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG004: No se encontró el número de orden de compra.", [], 500);
        }

        // Se guarda la imagen de evidencia en la base de datos documental
        $codeDocument1 = null;
        $arrResponseSave1 = $this->resourcesController->saveDocument($requestData['EVIDENCIA1'],'GEAD',$requestData['NOMBRE_EVIDENCIA1'],'FO',$requestData['NUMERO_LINEA']);
        if ( $arrResponseSave1['error'] ) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, 'ERR_ISSUE_TRACKING_REG005:'.$arrResponseSave1['msg'], $arrResponseSave1['response'], 500);
        }
        $codeDocument1 = $arrResponseSave1['response'];
        
        // Se guarda la imagen de evidencia opcional en la base de datos documental
        $codeDocument2 = null;
        if ($requestData['EVIDENCIA1'] != '') {
            $arrResponseSave2 = $this->resourcesController->saveDocument($requestData['EVIDENCIA2'],'GEAD',$requestData['NOMBRE_EVIDENCIA2'],'FO',$requestData['NUMERO_LINEA']);
            if ( $arrResponseSave2['error'] ) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, 'ERR_ISSUE_TRACKING_REG006:'.$arrResponseSave2['msg'], $arrResponseSave2['response'], 500);
            }
            $codeDocument2 = $arrResponseSave2['response'];
        }
        
        // Se procede a registrar el reporte en la base de datos
        try {
            $validateInsert = DB::table('S002V01TSEPR')->insert([
                'SEPR_NUOR' => $orderNumber,
                'SEPR_TIPO' => $requestData['TIPO'],
                'SEPR_DESC' => $requestData['DESCRIPCION'],
                'SEPR_EVI1' => $codeDocument1,
                'SEPR_EVI2' => $codeDocument2,
                'SEPR_NULI' => $requestData['NUMERO_LINEA'],
                'SEPR_USRE' => $user,
                'SEPR_FERE' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
                'SEPR_FEAR' => DB::raw('CURRENT_TIMESTAMP')
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG007: Ocurrió un error al hacer la inserción en la base.", $th->getMessage(), 500);
        }
        // Se valida que se haya registrado correctamente
        if (!$validateInsert) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_REG008: No se pudo ingresar el reporte en la base.", [], 500);
        }
        // Se guardan todos los cambios
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Registro de Reporte Exitoso");
    }

    public function getIssueTracking($line) {
        DB::beginTransaction();
        try {
            $arrIssueTracking = DB::table('S002V01TSEPR')
                ->where('SEPR_NULI', '=', $line)
                ->where('ORCO_NULI', '=', $line)
                ->where('DESP_NULI', '=', $line)
                ->join('S002V01TORCO', 'SEPR_NUOR', '=', 'ORCO_NUOR')
                ->join('S002V01TDESP', 'DESP_IDDE', '=', 'ORCO_NUDE')
                ->get([
                    'SEPR_IDPR',
                    'SEPR_NUOR',
                    'DESP_NOMB',
                    'SEPR_TIPO',
                    'SEPR_DESC',
                    'SEPR_RESO',
                    'SEPR_EVI1',
                    'SEPR_EVI2',
                    'SEPR_ESTA',
                    'SEPR_USRE',
                    'SEPR_FERE',
                    'SEPR_USMO',
                    'SEPR_FEMO',
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_GET000: Ocurrió un error al obtener los datos.", $th->getMessage(), 500);
        }

        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $arrIssueTracking);
    }

    public function resolutionIssueTracking(Request $request) {
        $validator = Validator::make($request->all(),[
            'NUMERO_SEGUIMIENTO' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_ISSUE_TRACKING_RES000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $requestData = $request->all();
        
        // Se obtiene el usuario encriptado
        try {
            $user = $this->encController->decrypt($requestData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES001: Ocurrió un error al obtener el usuario.", [], 500);
        }

        // Se obtiene el número de orden enctriptado
        try {
            $trackingNumber = $this->encController->decrypt($requestData['NUMERO_SEGUIMIENTO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES002: Ocurrió un error al obtener el usuario.", [], 500);
        }

        // Se valida el número de seguimiento
        try {
            $validateExists = DB::table('S002V01TSEPR')
                ->where('SEPR_IDPR', '=', $trackingNumber)
                ->where('SEPR_NULI', '=', $requestData['NUMERO_LINEA'])
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES003: Ocurrió un error al validar el número de seguimiento.", [], 500);
        }
        if (!$validateExists) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES004: No se encontró el número de seguimiento seleccionado.", [], 500);
        }

        try {
            $validateUpdate = DB::table('S002V01TSEPR')->where('SEPR_IDPR', '=', $trackingNumber)->where('SEPR_NULI', '=', $requestData['NUMERO_LINEA'])->update([
                'SEPR_ESTA' => 'Resuelto',
                'SEPR_RESO' => $requestData['DESCRIPCION'],
                'SEPR_USRE' => $user,
                'SEPR_FEMO' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
                'SEPR_FEAR' => DB::raw('CURRENT_TIMESTAMP')
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES005: Ocurrió un error al modificar los registros de seguimiento.", [], 500);
        }

        if (!$validateUpdate) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ISSUE_TRACKING_RES006: No se pudo modificar los registros de seguimiento.", [], 500);
        }
        
        // Se guardan todos los cambios
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Modificación de Reporte Exitoso");
    }
}