<?php

namespace App\Repositories;

use App\Models\Procedure;
use App\Models\ProcedureRoute;
use Config\Database;
use PDO;

class ProcedureRepository
{
    public function routes($procedure)
    {
        return ProcedureRoute::where('procedure_id', $procedure->id);
    }

    public function getVirtualProcedures()
    {
        $db = Database::getConnection();
        $stmt = $db->prepare("
            SELECT pr.* 
            FROM procedures pr
            INNER JOIN modalities m ON pr.modality_id = m.id
            WHERE (m.description = 'VIRTUAL' OR m.description = 'MIXTO')
            AND pr.deleted_at IS NULL
            AND m.deleted_at IS NULL
            ORDER BY pr.description ASC
        ");
        $stmt->execute();

        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $procedures = [];

        foreach ($results as $row) {
            $procedure = new Procedure();
            foreach ($row as $key => $value) {
                $procedure->$key = $value;
            }
            $procedures[] = $procedure;
        }

        return $procedures;
    }

    public function orderedRoutes($procedure)
    {
        $routes = $this->routes($procedure);
        return self::orderRoutes($routes);
    }

    private static function orderRoutes($routes)
    {
        $stepsById = [];
        foreach ($routes as $route) {
            $stepsById[$route->id] = $route;
        }

        $orderedRoutes = [];
        foreach ($routes as $route) {
            if ($route->previous_step_id === null) {
                $orderedRoutes[] = $route;
                break;
            }
        }

        while (!empty($orderedRoutes)) {
            $lastStep = end($orderedRoutes);
            if ($lastStep->next_step_id && isset($stepsById[$lastStep->next_step_id])) {
                $orderedRoutes[] = $stepsById[$lastStep->next_step_id];
            } else {
                break;
            }
        }

        return $orderedRoutes;
    }

    public function getFirstNodeByProcedure($procedureId)
    {
        $db = Database::getConnection();
        $query = "SELECT * FROM procedure_routes 
                WHERE procedure_id = ? AND previous_step_id IS NULL 
                AND active = 1 
                AND deleted_at IS NULL
                LIMIT 1";

        $stmt = $db->prepare($query);
        $stmt->execute([$procedureId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($row) {
            $route = new ProcedureRoute();
            $route->id = $row['id'];
            $route->procedure_id = $row['procedure_id'];
            $route->group_id = $row['group_id'];
            $route->subgroup_id = $row['subgroup_id'];
            $route->previous_step_id = $row['previous_step_id'];
            $route->next_step_id = $row['next_step_id'];
            return $route;
        }

        return null;
    }

    public function getFinalNodeByProcedure($procedureId)
    {
        $db = Database::getConnection();
        $query = "SELECT * FROM procedure_routes 
                WHERE procedure_id = ? 
                AND next_step_id IS NULL 
                AND active = 1 
                AND deleted_at IS NULL
                LIMIT 1";

        $stmt = $db->prepare($query);
        $stmt->execute([$procedureId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($row) {
            $route = new ProcedureRoute();
            $route->id = $row['id'];
            $route->procedure_id = $row['procedure_id'];
            $route->group_id = $row['group_id'];
            $route->subgroup_id = $row['subgroup_id'];
            $route->previous_step_id = $row['previous_step_id'];
            $route->next_step_id = $row['next_step_id'];
            return $route;
        }

        return null;
    }
}