<?php

namespace App\Http\Controllers;

// Controladores
use App\CorridaAnalito;
use App\Http\Controllers\Controller;
use App\Http\Controllers\LaboratorioController;
use App\Http\Controllers\UsuarioController;
use App\Http\Controllers\AreaController;

// Modelos
use App\CorridaArea;
use Illuminate\Support\Facades\DB;

// Historicos
use App\Http\Historico\CorridaAreaHistorico;

// Requests
use Illuminate\Http\Request;
use App\Http\Requests\CorridaAreaRequest;

// Sesion
use Auth;
use Exception;

class CorridaAreaController extends Controller{

    protected $tableCorridaArea;
    protected $historico;

    public function __construct(){
        $this->tableCorridaArea = new CorridaArea();
    }


    public function section(Request $req){
        $corridasArea = self::list($req->id_laboratorio, $req->id_area);
        $laboratorios = LaboratorioController::listAll();
        $areas = AreaController::list();

        $areasActuales = [];
        foreach ($corridasArea as $corridaArea){
            $corridaArea['analitos'] = $this->getAnalitosCorrida($corridaArea['id_corrida_area']);
            if(!in_array($corridaArea['area_id_area'], $areasActuales)){
                $areasActuales[] = $corridaArea['area_id_area'];
            }
        }

        $analitosActuales = [];
        $corridaAnalitos = CorridaAnalito::query()->get();
        foreach ($corridaAnalitos as $corridaAnalito){
            foreach($corridasArea as $corridaArea){
                if($corridaArea['id_corrida_area'] == $corridaAnalito['corrida_area_id_corrida_area']){
                    if(!in_array($corridaAnalito['analito_id_analito'], $analitosActuales)){
                        $analitosActuales[] = $corridaAnalito['analito_id_analito'];
                    }
                }
            }
        }

        return view("corridaArea.corridaAreaSection")
            ->with("nomSection","SeeSectionCorridaArea")
            ->with("laboratorios",$laboratorios)
            ->with("areas",$areas)
            ->with("corridasArea",$corridasArea)
            ->with("numeroAreasEP09", count($areasActuales))
            ->with("numeroAnalitosEP09", count($analitosActuales));
    }


    public function create(){
        $laboratorios = LaboratorioController::listAll();
        $areas = AreaController::list();
        return view("corridaArea.corridaAreaCreate")
            ->with("laboratorios",$laboratorios)
            ->with("areas",$areas);
    }


    public function index(Request $req){

        $corridasArea = self::list($req->id_laboratorio, $req->id_area);
        $areasActuales = [];
        foreach ($corridasArea as $corridaArea){
            $corridaArea['analitos'] = $this->getAnalitosCorrida($corridaArea['id_corrida_area']);
            if(!in_array($corridaArea['area_id_area'], $areasActuales)){
                $areasActuales[] = $corridaArea['area_id_area'];
            }
        }

        $analitosActuales = [];
        $corridaAnalitos = CorridaAnalito::query()->get();
        foreach ($corridaAnalitos as $corridaAnalito){
            foreach($corridasArea as $corridaArea){
                if($corridaArea['id_corrida_area'] == $corridaAnalito['corrida_area_id_corrida_area']){
                    if(!in_array($corridaAnalito['analito_id_analito'], $analitosActuales)){
                        $analitosActuales[] = $corridaAnalito['analito_id_analito'];
                    }
                }
            }
        }

        return view("corridaArea.corridaAreaIndex")
            ->with("numeroAnalitosEP09", count($analitosActuales))
            ->with("numeroAreasEP09", count($areasActuales))
            ->with("corridasArea",$corridasArea);
    }


    public function store(CorridaAreaRequest $req){

        $user = Auth::user();
        $client = DB::table("super_admin")
        ->where("id", $user->super_admin_id)
        ->first();
        $users = DB::table("corrida_area")
        ->where("client", $user->super_admin_id)
        ->count();

        if ($users < $client->num_project) {

            $this->historico = new CorridaAreaHistorico();
            $this->historico->store("store", $req);

            $this->tableCorridaArea->laboratorio_id_laboratorio = $req->id_laboratorio;
            $this->tableCorridaArea->area_id_area = $req->id_area;
            $this->tableCorridaArea->fecha_inicio = $req->fecha_inicio;
            $this->tableCorridaArea->client = $user->super_admin_id;
            $this->tableCorridaArea->usuario_id_usuario = $user->id_usuario;
            $this->tableCorridaArea->save();
        } else {
            throw new Exception('División por cero.');
        }
    }

    public static function getAnalitosCorrida($idProyectoCorrida)
    {
        $analitos = DB::table("corrida_analito")
            ->select("analito.nom_analito")
            ->join("analito", "analito.id_analito", "=", "corrida_analito.analito_id_analito")
            ->where("corrida_analito.corrida_area_id_corrida_area", $idProyectoCorrida)
            ->get();
        $listaAnalitos = [];
        foreach ($analitos as $analito) {
            $listaAnalitos[] = $analito->nom_analito;
        }
        if (count($listaAnalitos) > 0) {
            return implode(", ", $listaAnalitos);
        } else {
            return "No hay analitos";
        }
    }

    public static function list($laboratorio = "",$area = ""){

        if(Auth::user()->rol_id_rol == 5) {
            $tableCorridaArea = new CorridaArea();
            $obj_bd = $tableCorridaArea
                ->select(
                    "area.*",
                    "laboratorio.*",
                    "usuario.*",
                    "corrida_area.id_corrida_area",
                    "corrida_area.area_id_area",
                    "corrida_area.fecha_inicio",
                    "corrida_area.estado as estado_corrida_area",
                    "super_admin.name as client_name"
                )
                ->join("area", "area.id_area", "=", "corrida_area.area_id_area")
                ->join("laboratorio", "laboratorio.id_laboratorio", "=", "corrida_area.laboratorio_id_laboratorio")
                ->join("usuario", "usuario.id_usuario", "=", "corrida_area.usuario_id_usuario")
                ->join("super_admin", "super_admin.id", "=", "corrida_area.client")
                ->orderBy("corrida_area.estado","desc")
                ->orderBy("laboratorio.no_laboratorio","asc")
                ->orderBy("area.nom_area","asc");

            if($laboratorio != "" && $area != ""){ // Si tanto el area como el laboratorio estan definidos
                $obj_bd->where([
                    ["laboratorio.id_laboratorio","=",$laboratorio],
                    ["area.id_area","=",$area]
                ]);
            } else if($laboratorio != "") { // Si solo el laboratorio esta definido
                $obj_bd->where("laboratorio.id_laboratorio", $laboratorio);
            } else if($area != ""){ // Si solo el area esta definida
                $obj_bd->where("area.id_area", $area);
            }
            return $obj_bd->get();
        } else {
            if(Auth::user()->rol_id_rol == 1){ // Administrador total
                $tableCorridaArea = new CorridaArea();
                $obj_bd = $tableCorridaArea
                    ->select(
                        "area.*",
                        "laboratorio.*",
                        "usuario.*",
                        "corrida_area.id_corrida_area",
                        "corrida_area.area_id_area",
                        "corrida_area.fecha_inicio",
                        "corrida_area.estado as estado_corrida_area"
                    )
                    ->join("area", "area.id_area", "=", "corrida_area.area_id_area")
                    ->join("laboratorio", "laboratorio.id_laboratorio", "=", "corrida_area.laboratorio_id_laboratorio")
                    ->join("usuario", "usuario.id_usuario", "=", "corrida_area.usuario_id_usuario")
                    ->where("corrida_area.client",Auth::user()->super_admin_id)
                    ->orderBy("corrida_area.estado","desc")
                    ->orderBy("laboratorio.no_laboratorio","asc")
                    ->orderBy("area.nom_area","asc");

                if($laboratorio != "" && $area != ""){ // Si tanto el area como el laboratorio estan definidos
                    $obj_bd->where([
                        ["laboratorio.id_laboratorio","=",$laboratorio],
                        ["area.id_area","=",$area]
                    ]);
                } else if($laboratorio != "") { // Si solo el laboratorio esta definido
                    $obj_bd->where("laboratorio.id_laboratorio", $laboratorio);
                } else if($area != ""){ // Si solo el area esta definida
                    $obj_bd->where("area.id_area", $area);
                }
                return $obj_bd->get();
            } else { // Cualquier otro tipo de usuario
                $tableCorridaArea = new CorridaArea();
                $obj_bd = $tableCorridaArea
                    ->select(
                        "area.*",
                        "laboratorio.*",
                        "usuario.*",
                        "corrida_area.id_corrida_area",
                        "corrida_area.area_id_area",
                        "corrida_area.fecha_inicio",
                        "corrida_area.estado as estado_corrida_area"
                    )
                    ->join("area", "area.id_area", "=", "corrida_area.area_id_area")
                    ->join("laboratorio", "laboratorio.id_laboratorio", "=", "corrida_area.laboratorio_id_laboratorio")
                    ->join("usuario_laboratorio", "laboratorio.id_laboratorio", "=", "usuario_laboratorio.laboratorio_id_laboratorio")
                    ->join("usuario", "usuario.id_usuario", "=", "corrida_area.usuario_id_usuario")
                    ->where("corrida_area.client",Auth::user()->super_admin_id)
                    ->orderBy("corrida_area.estado","desc")
                    ->orderBy("laboratorio.no_laboratorio","asc")
                    ->orderBy("area.nom_area","asc");

                if($laboratorio != "" && $area != ""){ // Si tanto el area como el laboratorio estan definidos
                    $obj_bd->where([
                        ["laboratorio.id_laboratorio","=",$laboratorio],
                        ["area.id_area","=",$area],
                        ["usuario_laboratorio.usuario_id_usuario", "=", Auth::user()->id_usuario]
                    ]);
                } else if($laboratorio != "") { // Si solo el laboratorio esta definido
                    $obj_bd->where([
                        ["laboratorio.id_laboratorio", $laboratorio],
                        ["usuario_laboratorio.usuario_id_usuario", "=", Auth::user()->id_usuario]
                    ]);
                } else if($area != ""){ // Si solo el area esta definida
                    $obj_bd->where([
                        ["area.id_area", $area],
                        ["usuario_laboratorio.usuario_id_usuario", "=", Auth::user()->id_usuario]
                    ]);
                } else {
                    $obj_bd->where([
                        ["usuario_laboratorio.usuario_id_usuario", "=", Auth::user()->id_usuario]
                    ]);
                }

                return $obj_bd->get();
            }
        }
    }

    public static function listItem($id_corrida_area){
        $tableCorridaArea = new CorridaArea();
        return $tableCorridaArea
            ->select(
                "laboratorio.*",
                "area.*",
                "corrida_area.id_corrida_area",
                "corrida_area.laboratorio_id_laboratorio",
                "corrida_area.area_id_area",
                "corrida_area.fecha_inicio",
                "corrida_area.estado as estado_corrida_area"
                )
            ->join("laboratorio","laboratorio.id_laboratorio","=","corrida_area.laboratorio_id_laboratorio")
            ->join("area","area.id_area","=","corrida_area.area_id_area")
            ->where("id_corrida_area", "=", $id_corrida_area)
            ->first();
    }


    public static function listAll(){

        $tableCorridaArea = new CorridaArea();

        if(Auth::user()->rol_id_rol == 1){ // para administrador total
            return $tableCorridaArea
            ->select(
                "area.*",
                "laboratorio.*",
                "corrida_area.id_corrida_area",
                "corrida_area.fecha_inicio",
                "corrida_area.estado as estado_corrida_area"
            )
            ->join("area", "area.id_area", "=", "corrida_area.area_id_area")
            ->join("laboratorio", "laboratorio.id_laboratorio", "=", "corrida_area.laboratorio_id_laboratorio")
            ->orderBy("corrida_area.id_corrida_area","asc")
            ->get();
        } else { // Si es otro usuario
            // Solo pueda ver los que tiene asignados
            $id_usuario = Auth::user()->id_usuario;
            return $tableCorridaArea
                ->select(
                    "area.*",
                    "laboratorio.*",
                    "corrida_area.id_corrida_area",
                    "corrida_area.fecha_inicio",
                    "corrida_area.estado as estado_corrida_area"
                )
                ->join("area", "area.id_area", "=", "corrida_area.area_id_area")
                ->join("laboratorio", "laboratorio.id_laboratorio", "=", "corrida_area.laboratorio_id_laboratorio")
                ->orderBy("corrida_area.id_corrida_area","asc")
                ->where(function($query) use($id_usuario){
                    $id_labs = UsuarioController::listLaboratorios($id_usuario, "array", "id_laboratorio");
                    return $query->whereIn("laboratorio.id_laboratorio",$id_labs);
                })
                ->get();
        }

    }

    public function verUsuarios(Request $req){
        $corridaArea = self::ListItem($req->id_reference);
        $users = UsuarioController::listUsersByLabForProject("corrida_area","id_corrida_area",$corridaArea->id_corrida_area);
        return view("corridaArea.corridaAreaAccess")
            ->with("corridaArea",$corridaArea)
            ->with("users",$users);
    }


    public function edit(Request $req){

        $corridaArea = self::ListItem($req->id_reference);
        $laboratorios = LaboratorioController::listAll();
        $areas = AreaController::list();

        return view("corridaArea.corridaAreaEdit")
            ->with("laboratorios",$laboratorios)
            ->with("areas",$areas)
            ->with("corridaArea",$corridaArea);
    }


    public function listHTML(){

        $corridasArea = Self::listAll();

        return view("corridaArea.corridaAreaList")
            ->with("corridasArea",$corridasArea);
    }


    public static function getAreaById($id_corrida){ // Obtener el area de una corrida
        $tableCorridaArea = new CorridaArea();
        return $tableCorridaArea
            ->where("id_corrida_area",$id_corrida)
            ->first()["area_id_area"];
    }


    public function destroy(Request $req){

        $this->historico = new CorridaAreaHistorico();
        $this->historico->store("destroy", $req);

        $this->tableCorridaArea
            ->where("id_corrida_area",$req->id)
            ->delete();
    }


    public function status(Request $req){

        $this->historico = new CorridaAreaHistorico();
        $this->historico->store("status", $req);

        $statusNow = $this->tableCorridaArea
            ->where("id_corrida_area",$req->id)
            ->first()
            ->estado;

        $registroUpdate = $this->tableCorridaArea
            ->where("id_corrida_area",$req->id);

        if($statusNow == 1){
            $registroUpdate->update(["estado" => 0]);
        } else {
            $registroUpdate->update(["estado" => 1]);
        }
    }


    public function show(Request $req){
        $area = $this->tableArea
            ->where("id_area",$req->id)
            ->first();

        return view("area.areaShow")
            ->with("area",$area)
            ->with("campo",$req->campo);
    }


    public function update(CorridaAreaRequest $req){

        $this->historico = new CorridaAreaHistorico();
        $this->historico->store("update", $req);

        $corridaArea = $this->tableCorridaArea
            ->where("id_corrida_area",$req->id)
            ->first();

        $corridaArea->update([
            "laboratorio_id_laboratorio" => $req->id_laboratorio,
            "area_id_area" => $req->id_area,
            "fecha_inicio" => $req->fecha_inicio
        ]);
    }
}
