<?php session_start();
/*      Copyright 2023 Flávio Ribeiro

        This file is part of OCOMON.

        OCOMON is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 3 of the License, or
        (at your option) any later version.
        OCOMON is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with Foobar; if not, write to the Free Software
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

if (!isset($_SESSION['s_logado']) || $_SESSION['s_logado'] == 0) {
    $_SESSION['session_expired'] = 1;
    echo "<script>top.window.location = '../../index.php'</script>";
    exit;
}

require_once __DIR__ . "/" . "../../includes/include_basics_only.php";
require_once __DIR__ . "/" . "../../includes/classes/ConnectPDO.php";
require_once __DIR__ . "/" . "../../includes/classes/worktime/Worktime.php";
include_once __DIR__ . "/" . "../../includes/functions/getWorktimeProfile.php";

use includes\classes\ConnectPDO;

$conn = ConnectPDO::getInstance();
$exception = "";
$criteria = [];
$criteriaText = "";
$data = [];
$data['success'] = true;
$data['message'] = "";
$data['total'] = 0;
$uareas = explode(',', (string)$_SESSION['s_uareas']);
$terms = "";
$termsTotal = "";
$holidays = getHolidays($conn);
$config = getConfig($conn);
$percLimit = $config['conf_sla_tolerance']; 
$platformScopeField = getConfigValue($conn, 'PLATFORM_SCOPE_CUSTOM_FIELD') ?? '';
//getTicketCustomFields

$ticketsResult = [];


$isAdmin = $_SESSION['s_nivel'] == 1;
$mvpBaseDay = getConfigValue($conn, 'MVP_BASE_DAY') ?? 1;

$debugMode = false;
// $debugMode = ($_SESSION['s_usuario'] == 'flaviorib@gmail.com');


$labelsByStates = [
    1 => TRANS('STATE_OPEN_CLOSE_IN_SEARCH_RANGE'),
    2 => TRANS('STATE_OPEN_IN_SEARCH_RANGE'),
    3 => TRANS('STATE_OPEN_IN_SEARCH_RANGE_CLOSE_ANY_TIME'),
    4 => TRANS('STATE_OPEN_ANY_TIME_CLOSE_IN_SEARCH_RANGE'),
    5 => TRANS('STATE_JUST_OPEN_IN_SEARCH_RANGE')
];

$slaIndicatorLabel = [];
$slaIndicatorLabel[1] = TRANS('SMART_NOT_IDENTIFIED');
$slaIndicatorLabel[2] = TRANS('SMART_IN_SLA');
$slaIndicatorLabel[3] = TRANS('SMART_IN_SLA_TOLERANCE');
$slaIndicatorLabel[4] = TRANS('SMART_OUT_SLA');

$textSlaColumn = [
    'gray-circle.svg' => TRANS('SMART_NOT_IDENTIFIED'),
    'green-circle.svg' => TRANS('SMART_IN_SLA'),
    'yellow-circle.svg' => TRANS('SMART_IN_SLA_TOLERANCE'),
    'red-circle.svg' => TRANS('SMART_OUT_SLA'),
];



/* Inicialização dos Critérios da consulta */
$criteria['client'] = TRANS('CLIENT') . ':&nbsp;' . TRANS('ALL');
// $criteria['treater'] = TRANS('WORKER') . ':&nbsp;' . TRANS('ALL');
$criteria['area'] = TRANS('AREA') . ':&nbsp;' . TRANS('ALL');
$criteria['state'] = TRANS('CONTEXT') . ':&nbsp;' . TRANS('STATE_OPEN_CLOSE_IN_SEARCH_RANGE');

$post = $_POST;

$hora_inicio = ' 00:00:00';
$hora_fim = ' 23:59:59';

$data['client'] = (isset($post['client']) ? (int)$post['client'] : "");
$data['area'] = (isset($post['area']) ? (int)$post['area'] : "");

$data['treater'] = (isset($post['treater']) ? (int)$post['treater'] : "");

if (!$isAdmin) {
    $data['treater'] = $_SESSION['s_uid'];
}

$data['d_ini'] = (isset($post['d_ini']) && isValidDate($post['d_ini']) ? dateDB($post['d_ini'] . $hora_inicio) : '');
$data['d_fim'] = (isset($post['d_fim']) && isValidDate($post['d_fim']) ? dateDB($post['d_fim'] . $hora_fim) : '');

$data['state'] = (isset($post['state']) && !empty($post['state']) ? (int)$post['state'] : 1);

$data['generate_chart'] = 0;



if (empty($data['d_ini']) || empty($data['d_fim']) || ($data['d_ini'] > $data['d_fim'])) {
    $data['success'] = false;
    $data['field_id'] = "d_ini";
    $data['message'] = TRANS('MSG_CHECK_PERIOD');
    $data['message'] = message('warning', 'Ooops!', $data['message'], '', '');
    echo json_encode($data);
    return false;
}



if (!empty($data['client'])) {
    $terms .= " AND o.client = {$data['client']} ";
    $termsTotal .= $terms;
    $criteria['client'] = TRANS('CLIENT') . ':&nbsp;<b>' . getClients($conn, $data['client'])['nickname'] . '</b>';
}

$limited_areas = false;
$string_area_names = "";
if (empty($data['area']) && isAreasIsolated($conn) && $_SESSION['s_nivel'] != 1) {
    /* Visibilidade isolada entre áreas para usuários não admin */
    $limited_areas = true;
    $u_areas = $_SESSION['s_uareas'];

    $terms .= " AND o.sistema IN ({$u_areas}) ";
    $termsTotal .= $terms;

    $array_areas_names = getUserAreasNames($conn, $u_areas);
    $string_area_names = implode(", ", array_filter($array_areas_names));
} elseif (!empty($data['area'])) {

    $string_area_names = getAreaInfo($conn, $data['area'])['area_name'];

    $terms .= " AND o.sistema = {$data['area']} ";
    $termsTotal .= $terms;
    $criteria['area'] = TRANS('AREA') . ':&nbsp;<b>' . $string_area_names . '</b>';
}




if (!empty($data['treater'])) {
    $terms .= " AND u.user_id = {$data['treater']} ";
    $termsTotal .= $terms;
    $criteria['treater'] = TRANS('WORKER') . ':&nbsp;<b>' . getUserInfo($conn, $data['treater'])['nome'] . '</b>';
}


$client_filter = [];

// $termsTotal = "";
$chart_title_sufix = '_chart_title';
$chart_1_prefix = 'chart_01';


/* Período */
$criteria['range'] = TRANS('RANGE_FROM_TO') . ':&nbsp;<b>' . $post['d_ini'] . ' - ' . $post['d_fim'] . '</b>';

/* Contexto */
$criteria['state'] = TRANS('CONTEXT') . ':&nbsp;<b>' . $labelsByStates[$data['state']] . '</b>';

$_SESSION['s_rep_filters']['client'] = $data['client'];
$_SESSION['s_rep_filters']['area'] = $data['area'];
$_SESSION['s_rep_filters']['state'] = $data['state'];
$_SESSION['s_rep_filters']['d_ini'] = $post['d_ini'];
$_SESSION['s_rep_filters']['d_fim'] = $post['d_fim'];


/* Montagem do texto dos critérios */
$criteriaText = implode(' | ', $criteria);
if ($limited_areas) {
    $criteriaText .= " <br />(". TRANS('RESULT_LIMITED_BY_PERMISSIONS').")";
}
$data['criteria'] = $criteriaText;
/* Final da montagem dos critérios */


$clausulesByStates = [
    1 => " AND o.data_abertura >= '{$data['d_ini']}' AND o.data_abertura <= '{$data['d_fim']}' AND 
    o.data_fechamento IS NOT NULL AND o.data_fechamento >= '{$data['d_ini']}' AND o.data_fechamento <= '{$data['d_fim']}' ",
    2 => " AND o.data_abertura >= '{$data['d_ini']}' AND o.data_abertura <= '{$data['d_fim']}' AND 
    (o.data_fechamento >= '{$data['d_fim']}' OR o.data_fechamento IS NULL) ",
    3 => " AND o.data_abertura >= '{$data['d_ini']}' AND o.data_abertura <= '{$data['d_fim']}' AND 
    o.data_fechamento IS NOT NULL ",
    4 => " AND o.data_fechamento >= '{$data['d_ini']}' AND o.data_fechamento <= '{$data['d_fim']}' ",
    5 => " AND o.data_abertura >= '{$data['d_ini']}' AND o.data_abertura <= '{$data['d_fim']}' "
];


$data['table_1'] = [];

$data['table_2'] = [];
$data['operators'] = [];

$data['tickets'] = [];
$data['chart_1'] = [];



//COALESCE (dep.proj_id, 0) AS proj_id,
$sql = "SELECT o.numero 
        FROM 
            ocorrencias o, 
            ocodeps dep 
        WHERE
            o.numero = dep.dep_pai 
            {$terms}
            {$clausulesByStates[$data['state']]}
        GROUP BY o.numero";

    try {
        $res = $conn->prepare($sql);
        $res->execute();
        if ($res->rowCount()) {
            $data['table_1'] = $res->fetchAll();
        }
    } catch (PDOException $e) {
        $data['success'] = false;
        $data['message'] = message('warning', 'Ooops!', $e->getMessage(),'');
        echo json_encode($data);
        return false;
    }

    if (count($data['table_1']) == 0) {
        $data['success'] = false;
        $data['message'] = message('warning', 'Ooops!', TRANS('NO_RECORDS_FOUND') . $exception,'');
        echo json_encode($data);
        return false;
    }


    /**
     * 1 - Checar se cada ticket retornado é o primeiro chamado do projeto, pois, eventualmente, pode não ser.
     * 2 - Se não for o primeiro ticket, descartar. Pois ele será filho de algum dos tickets já retornados.
     * 3 - Para cada tícket que for o primeiro de cada projeto, fazer todos os processamentos já utilizados no `project_details.php`.
     */

    $fatherTickets = [];
    $ticketsData = [];
    $projects = [];
    /* Filtrando apenas pelos chamados origem dos projetos */
    foreach ($data['table_1'] as $ticket) {
        $storeParent = [];
        $firstOfAll = getFirstFather($conn, $ticket['numero'], $storeParent);
        if ($firstOfAll == $ticket['numero']) {
            $fatherTickets[] = $ticket['numero'];
        } 
    }

    /* Todo o processamento será feito aqui a partir de cada ticket origem */
    foreach ($fatherTickets as $ticket) {
    
        $storeSons = [];
        $relations = getTicketDownRelations($conn, $ticket, $storeSons);
    
        $textProjectTickets = implode(',', array_keys($relations));


        $sql = $QRY["ocorrencias_full_ini"] . " 
                WHERE 
                    o.numero IN ({$textProjectTickets}) 
                ORDER BY numero";
        try {
            $res = $conn->query($sql);
            // $ticketsData[$ticket] = $res->fetchAll();
            foreach ($res->fetchAll() as $row) {
                $ticketsResult[$ticket][$row['numero']] = $row;
            }

        } catch(Exception $e) {
            $data['success'] = false;
            $data['message'] = message('warning', 'Ooops!', $e->getMessage(),'');
            echo json_encode($data);
            return false;
        }
        
    
    }
    

    $outputData = [];
    $idx = 0;
    foreach ($ticketsResult as $ticket => $row) {

        $outputData[$idx]['father'] = $ticket;
        $outputData[$idx]['description'] = toHtml($row[$ticket]['descricao']);
        $outputData[$idx]['root_issue'] = $row[$ticket]['problema']; //prob_cod
        $outputData[$idx]['sla_solucao'] = $row[$ticket]['sla_solucao'] ?? TRANS('MSG_NOT_DEFINED'); 

        $ticketPlatformScopeValue = '';
        if (!empty($platformScopeField)) {
            $ticketPlatformScope = getTicketCustomFields($conn, $ticket, $platformScopeField);
            $ticketPlatformScopeValue = (!empty($ticketPlatformScope['field_value']) ? $ticketPlatformScope['field_value'] : '');
        }
        $outputData[$idx]['platform_scope'] = $ticketPlatformScopeValue;
        $outputData[$idx]['area'] = $row[$ticket]['area'];

        $subtickets = [];
        $areas = [];
        $issues = [];
        $areasSumTimes = [];
        $areasSumTimesVerbose = [];
        $closingDates = [];
        $colTVNewArray = [];
        $totalFilteredSolutionSeconds = 0;
        $totalAbsSolutionSeconds = 0;
        $absoluteTime = [];
        $absoluteTimeInSecs = [];

        foreach ($row as $subticket => $subData) {

            /** ************************************************************ 
             *** Processos para os cálculos de tempos de cada chamado ******
            * *************************************************************/
            $referenceDate = (!empty($subData['oco_real_open_date']) ? $subData['oco_real_open_date'] : $subData['data_abertura']);
            $dataAtendimento = $subData['data_atendimento']; //data da primeira resposta ao chamado
            $dataFechamento = $subData['data_fechamento'];

            $profileCod = getProfileCod($conn, $_SESSION['s_wt_areas'], $subData['numero']);
            $worktimeProfile = getWorktimeProfile($conn, $profileCod);

            /* Objeto para o cálculo de Tempo válido de SOLUÇÃO - baseado no perfil de jornada de trabalho e nas etapas em cada status */
            $newWT = new WorkTime( $worktimeProfile, $holidays );
                
            /* Objeto para o cálculo de Tempo válido de RESPOSTA baseado no perfil de jornada de trabalho e nas etapas em cada status */
            $newWTResponse = new WorkTime( $worktimeProfile, $holidays );

            /* Objeto para checagem se o momento atual está coberto pelo perfil de jornada associado */
            $objWT = new Worktime( $worktimeProfile, $holidays );

            /* Realiza todas as checagens necessárias para retornar os tempos de resposta e solução para o chamado */
            $ticketTimeInfo = getTicketTimeInfo($conn, $newWT, $newWTResponse, $subData['numero'], $referenceDate, $dataAtendimento, $dataFechamento, $subData['status_cod'], $objWT);

            /* Retorna os leds indicativos (bolinhas) para os tempos de resposta e solução */
            $ledSlaResposta[$subData['numero']] = showLedSLA($ticketTimeInfo['response']['seconds'], $percLimit, $subData['sla_resposta_tempo']);
            $ledSlaSolucao[$subData['numero']] = showLedSLA($ticketTimeInfo['solution']['seconds'], $percLimit, $subData['sla_solucao_tempo']);

            /* Texto sobre os SLAs - para serem imprimíveis */
            $textSlaResposta[$subData['numero']] = $textSlaColumn[$ledSlaResposta[$subData['numero']]];
            $textSlaSolucao[$subData['numero']] = $textSlaColumn[$ledSlaSolucao[$subData['numero']]];

            $colTVNew = $ticketTimeInfo['solution']['time'];

            $responseResult = getSlaResult($ticketTimeInfo['response']['seconds'], $percLimit, $subData['sla_resposta_tempo']);
            $solutionResult = getSlaResult($ticketTimeInfo['solution']['seconds'], $percLimit, $subData['sla_solucao_tempo']);
            
            $arrayAbsoluteTime = absoluteTime($referenceDate, (!empty($dataFechamento) ? $dataFechamento : date('Y-m-d H:i:s')));
            $absoluteTime[$subData['numero']] = $arrayAbsoluteTime['inTime'];
            $absoluteTimeInSecs[$subData['numero']] = $arrayAbsoluteTime['inSeconds'];
            
            
            $absServiceTime[$subData['numero']] = absoluteTime((!empty($dataAtendimento) ? $dataAtendimento : $referenceDate), (!empty($dataFechamento) ? $dataFechamento : date('Y-m-d H:i:s')))['inTime'];

            $solution_from_response_seconds[$subData['numero']] = $ticketTimeInfo['solution']['seconds'] - $ticketTimeInfo['response']['seconds'];

            if ($solution_from_response_seconds[$subData['numero']] != 0) {
                $solution_from_response_time[$subData['numero']] = secToTime($solution_from_response_seconds[$subData['numero']])['verbose'];
            } else {
                $solution_from_response_time[$subData['numero']] = $ticketTimeInfo['solution']['time'];
            }

            $responseSeconds[$subData['numero']] = $ticketTimeInfo['response']['seconds'];
            $solutionSeconds[$subData['numero']] = $ticketTimeInfo['solution']['seconds'];

            $filteredSolutionTime[$subData['numero']] = $ticketTimeInfo['solution']['time'];
            $filteredResponseTime[$subData['numero']] = $ticketTimeInfo['response']['time'];
            /* Final dos processos de cálculos de tempo */



            $subtickets[] = $subticket;
            $areas[] = $subData['area'];
            $issues[] = $subData['problema'];

            /* Soma os tempos de solução para cada área - Sempre se considera que o chamado mantém a mesma área para todo o tempo */
            if (!empty($subData['area'])) {
                if (array_key_exists($subData['area'], $areasSumTimes)) {
                    $areasSumTimes[$subData['area']] += $ticketTimeInfo['solution']['seconds'];
                    $areasSumTimesVerbose[$subData['area']] = secToTime($areasSumTimes[$subData['area']])['verbose'];
                } else {
                    $areasSumTimes[$subData['area']] = (int)$ticketTimeInfo['solution']['seconds'];
                    $areasSumTimesVerbose[$subData['area']] = secToTime($areasSumTimes[$subData['area']])['verbose'];
                }
            }

            $totalFilteredSolutionSeconds += $ticketTimeInfo['solution']['seconds'];
            $totalAbsSolutionSeconds += $absoluteTimeInSecs[$subData['numero']];

        }
        $outputData[$idx]['subtickets'] = $subtickets;
        $outputData[$idx]['issues_count'] = array_count_values($issues); //key => value
        $outputData[$idx]['areas_count'] = array_count_values($areas); //key => value

        $textAreasCount = '';
        foreach ($outputData[$idx]['areas_count'] as $subArea => $subAreaValue) {
            $textAreasCount .= $subArea . ' (' . $subAreaValue . '), ';
        }
        $outputData[$idx]['text_areas_count'] = $textAreasCount;


        $outputData[$idx]['areas'] = array_unique($areas);
        $outputData[$idx]['areas_sum_times'] = $areasSumTimes;
        $outputData[$idx]['areas_sum_times_verbose'] = $areasSumTimesVerbose;
        $outputData[$idx]['absolute_time'] = $absoluteTime[$ticket];
        $outputData[$idx]['absolute_time_in_seconds'] = $totalAbsSolutionSeconds;
        $outputData[$idx]['filtered_time'] = $filteredSolutionTime[$ticket];
        $outputData[$idx]['filtered_time_in_seconds'] = $totalFilteredSolutionSeconds;

        $idx++;
    }


$data['tickets'] = $outputData;
$data['tickets']['title'] = TRANS('REPORT_BY_PROJECT');

echo json_encode($data);
return true;
