<?php

namespace App\Modules\GroupPassenger\Infraestructure;

use App\Modules\Group\Domain\GroupDateEnd;
use App\Modules\Group\Domain\GroupDateStart;
use App\Modules\GroupPassenger\Domain\GroupPassengerReportRepository;
use Illuminate\Support\Facades\DB;

class MysqlGroupPassengerReportRepository implements GroupPassengerReportRepository
{

    public function report(GroupDateStart $dateStart, GroupDateEnd $dateEnd)
    {
        $object = DB::select(
            "SELECT `pk`.`Package_Code` AS `Paquete`,
                    `t`.`Tour_Code` AS `Tour`,
                    `p`.`Id_Passenger` AS `IdPass`,
                    CONCAT(`p`.`Passenger_Name`, ' / ', `p`.`Passenger_LastName`) AS `Pasajero`,
                    DAYOFMONTH(`gp_aux`.`Group_DateStart`) AS `Dia_ida`,
                    MONTH(`gp_aux`.`Group_DateStart`) AS `Mes_ida`,
                    YEAR(`gp_aux`.`Group_DateStart`) AS `Anho_ida`,
                    DAYOFMONTH(`gp_aux`.`Group_DateEnd`) AS `Dia_retorno`,
                    MONTH(`gp_aux`.`Group_DateEnd`) AS `Mes_retorno`,
                    YEAR(`gp_aux`.`Group_DateEnd`) AS `Anho_retorno`,
                    `bt`.`BookingTour_TourDuration` AS `NoDias`,
                    ( CASE `p`.`Passenger_Gender` WHEN 1 THEN 'M' ELSE 'F' END ) AS `Sexo`,
                    YEAR(CURDATE())-YEAR(`p`.`Passenger_DOB`) + IF(DATE_FORMAT(CURDATE(),'%m-%d') > DATE_FORMAT(`p`.`Passenger_DOB`,'%m-%d'), 0 , -1 ) AS `Edad`,
                    `uc`.`UserCountry_Name` AS `Nacionalidad`,
                    `er`.`Id_ExternalReview` AS `IdExt`,
                    ( CASE WHEN `er`.`Id_External` IS NOT NULL THEN 'SI' ELSE 'NO' END ) AS `Tiene_TripAdvisor`,
                    COUNT(DISTINCT `Id_ExternalReview`) AS `Trip_Count`,
                    DAYOFMONTH(`er`.`ExternalReview_DateReview`) AS `Trip_Dia_llenado`,
                    MONTH(`er`.`ExternalReview_DateReview`) AS `Trip_Mes_llenado`,
                    YEAR(`er`.`ExternalReview_DateReview`) AS `Trip_Anho_llenado`,
                    `er`.`ExternalReview_Score` AS `Trip_Score`,
                    `er`.`ExternalReview_Value` AS `Trip_Comentario`,
                    `er`.`ExternalReview_Score` AS `Trip_Score`,
                    ( CASE WHEN `pr`.`Id_PassengerReview` IS NOT NULL THEN 'SI' ELSE 'NO' END ) AS `Tiene_Review`,
                    DAYOFMONTH(`pr`.`PassengerReview_DateUpdate`) AS `Dia_llenado`,
                    MONTH(`pr`.`PassengerReview_DateUpdate`) AS `Mes_llenado`,
                    YEAR(`pr`.`PassengerReview_DateUpdate`) AS `Anho_llenado`,
                    (
                        CONCAT(
                        '[',
                        GROUP_CONCAT(DISTINCT JSON_OBJECT(
                            'Id_Provider',              `gpv_p`.`Id_Provider`,
                            'Provider_BusinessName',    `gpv_p`.`Provider_BusinessName`,
                            'Id_TypeProvider',          `gpv_tp`.`Id_TypeProvider`,
                            'TypeProvider_Name',        `gpv_tp`.`TypeProvider_Name`
                            ) SEPARATOR ','),
                        ']'
                        )
                    ) AS `GroupProvider_JSON`,
                    (
                        CONCAT(
                        '[',
                        GROUP_CONCAT(DISTINCT JSON_OBJECT(
                            'Id_PassengerReview',       `pr`.`Id_PassengerReview`,
                            'PassengerReview_Status',   `pr`.`PassengerReview_Status`,
                            'PassengerReview_Values',   `pr`.`PassengerReview_Values`,
                            'PassengerReview_Comment',  `pr`.`PassengerReview_Comment`,
                            'PassengerReview_Score',    `pr`.`PassengerReview_Score`,
                            'PassengerReview_DateUpdate',`pr`.`PassengerReview_DateUpdate`,
                            'Id_Provider',              `pv`.`Id_Provider`,
                            'Provider_BusinessName',    `pv`.`Provider_BusinessName`,
                            'Id_TypeProvider',          `tp`.`Id_TypeProvider`,
                            'TypeProvider_Name',        `tp`.`TypeProvider_Name`,
                            'Id_Question',              `q`.`Id_Question`,
                            'Question_Type',            `q`.`Question_Type`,
                            'Question_General',         `q`.`Question_General`
                            ) SEPARATOR ','),
                        ']'
                        )
                    ) AS `PassengerReviewAll_JSON`
            FROM (
                    SELECT  `gp`.`Id_GroupPassenger`,
                            `gp`.`Id`,
                            `gp`.`GroupPassenger_Type`,
                            `gp`.`GroupPassenger_ReviewStatus`,
                            `g`.`Id_Group`,
                            `g`.`Group_DateStart`,
                            `g`.`Group_DateEnd`
                    FROM    `t_group_passenger` AS `gp` INNER JOIN
                            `t_group` AS `g` ON `g`.`Id_Group` = `gp`.`Id_Group` AND `g`.`Group_ServiceType` IN (1)
                    WHERE   `g`.`Group_DateStart` BETWEEN ? AND ?
                )   `gp_aux` INNER JOIN
                `t_booking_tour_passenger`  AS `btp`    ON `btp`.`Id_BookingTourPassenger` = `gp_aux`.`Id` AND `gp_aux`.`GroupPassenger_Type` = 1 INNER JOIN
                `t_booking_tour`            AS `bt`     ON `bt`.`Id_BookingTour` = `btp`.`Id_BookingTour` INNER JOIN
                `t_tour`                    AS `t`      ON `t`.`Id_Tour` = `bt`.`Id_Tour` INNER JOIN
                `t_package`                 AS `pk`     ON `pk`.`Id_Package` = `bt`.`Id_Package` INNER JOIN
                `t_passenger`               AS `p`      ON `p`.`Id_Passenger` = `btp`.`Id_Passenger` INNER JOIN
                `t_user_country`            AS `uc`     ON `uc`.`Id_UserCountry` = `p`.`Id_UserCountry` LEFT JOIN
                `t_group_provider`          AS `gpv`    ON `gpv`.`Id_Group` = `gp_aux`.`Id_Group` LEFT JOIN
                `t_provider`                AS `gpv_p`  ON `gpv_p`.`Id_Provider` = `gpv`.`Id_Provider`LEFT JOIN
                `t_type_provider`           AS `gpv_tp` ON `gpv_tp`.`Id_TypeProvider` = `gpv`.`Id_TypeProvider` LEFT JOIN
                `t_passenger_review`        AS `pr`     ON `pr`.`Id_GroupPassenger` = `gp_aux`.`Id_GroupPassenger` AND `gp_aux`.`GroupPassenger_ReviewStatus` = 2 LEFT JOIN
                `t_question`                AS `q`      ON `q`.`Id_Question` = `pr`.`Id_Question` LEFT JOIN
                `t_provider`                AS `pv`     ON `pr`.`Id_provider` = `pv`.`Id_Provider` LEFT JOIN
                `t_type_provider`           AS `tp`     ON `tp`.`Id_TypeProvider` = `pv`.`Id_TypeProvider` LEFT JOIN
                `t_external_review`         AS `er`     ON `er`.`Id_GroupPassenger` = `gp_aux`.`Id_GroupPassenger` AND `er`.`Id_External` = 1 AND `er`.`ExternalReview_Status` = 2
            GROUP BY `gp_aux`.`Id_GroupPassenger`
            ORDER BY `gp_aux`.`Group_DateStart` DESC, `gp_aux`.`Id_GroupPassenger` ASC
            ",
            [
                $dateStart->value(),
                $dateEnd->value()
            ]
        );
        $objects = $this->generateObjects($object);

        return $objects;
    }

    public function reportCategorized(GroupDateStart $dateStart, GroupDateEnd $dateEnd)
    {
        $object = DB::select(
            "SELECT CONCAT(`p`.`Passenger_Name`, ' / ', `p`.`Passenger_LastName`) AS `Pasajero`,
                    DAYOFMONTH(`gp_aux`.`Group_DateStart`) AS `Dia_ida`,
                    MONTH(`gp_aux`.`Group_DateStart`) AS `Mes_ida`,
                    YEAR(`gp_aux`.`Group_DateStart`) AS `Anho_ida`,
                    DAYOFMONTH(`gp_aux`.`Group_DateEnd`) AS `Dia_retorno`,
                    MONTH(`gp_aux`.`Group_DateEnd`) AS `Mes_retorno`,
                    YEAR(`gp_aux`.`Group_DateEnd`) AS `Anho_retorno`,
                    ( CASE `p`.`Passenger_Gender` WHEN 1 THEN 'M' ELSE 'F' END ) AS `Sexo`,
                    YEAR(CURDATE())-YEAR(`p`.`Passenger_DOB`) + IF(DATE_FORMAT(CURDATE(),'%m-%d') > DATE_FORMAT(`p`.`Passenger_DOB`,'%m-%d'), 0 , -1 ) AS `Edad`,
                    ( CASE WHEN `pr`.`Id_PassengerReview` IS NOT NULL THEN 'SI' ELSE 'NO' END ) AS `Tiene_Review`,
                    DAYOFMONTH(`pr`.`PassengerReview_DateUpdate`) AS `Dia_llenado`,
                    MONTH(`pr`.`PassengerReview_DateUpdate`) AS `Mes_llenado`,
                    YEAR(`pr`.`PassengerReview_DateUpdate`) AS `Anho_llenado`,
                    (
                        CONCAT(
                        '[',
                        GROUP_CONCAT(DISTINCT JSON_OBJECT(
                            'Id_PassengerReview',       `pr`.`Id_PassengerReview`,
                            'PassengerReview_Status',   `pr`.`PassengerReview_Status`,
                            'PassengerReview_Values',   `pr`.`PassengerReview_Values`,
                            'PassengerReview_Comment',  `pr`.`PassengerReview_Comment`,
                            'PassengerReview_Score',    `pr`.`PassengerReview_Score`,
                            'PassengerReview_DateUpdate',`pr`.`PassengerReview_DateUpdate`,
                            'Id_Question',              `q`.`Id_Question`,
                            'Question_Type',            `q`.`Question_Type`,
                            'Question_General',         `q`.`Question_General`
                            ) SEPARATOR ','),
                        ']'
                        )
                    ) AS `PassengerReviewAll_JSON`
            FROM (
                    SELECT  `gp`.`Id_GroupPassenger`,
                            `gp`.`Id`,
                            `gp`.`GroupPassenger_Type`,
                            `gp`.`GroupPassenger_ReviewStatus`,
                            `g`.`Id_Group`,
                            `g`.`Group_DateStart`,
                            `g`.`Group_DateEnd`
                    FROM    `t_group_passenger` AS `gp` INNER JOIN
                            `t_group` AS `g` ON `g`.`Id_Group` = `gp`.`Id_Group` AND `g`.`Group_ServiceType` IN (1)
                    WHERE   `g`.`Group_DateStart` BETWEEN ? AND ?
                )   `gp_aux` INNER JOIN
                `t_booking_tour_passenger`  AS `btp`    ON `btp`.`Id_BookingTourPassenger` = `gp_aux`.`Id` AND `gp_aux`.`GroupPassenger_Type` = 1 INNER JOIN
                `t_booking_tour`            AS `bt`     ON `bt`.`Id_BookingTour` = `btp`.`Id_BookingTour` INNER JOIN
                `t_passenger`               AS `p`      ON `p`.`Id_Passenger` = `btp`.`Id_Passenger` LEFT JOIN
                `t_passenger_review`        AS `pr`     ON `pr`.`Id_GroupPassenger` = `gp_aux`.`Id_GroupPassenger` AND `gp_aux`.`GroupPassenger_ReviewStatus` = 2 LEFT JOIN
                `t_question`                AS `q`      ON `q`.`Id_Question` = `pr`.`Id_Question`
            WHERE `pr`.`Id_PassengerReview` IS NOT NULL
            GROUP BY `gp_aux`.`Id_GroupPassenger`
            ORDER BY `gp_aux`.`Group_DateStart` DESC, `gp_aux`.`Id_GroupPassenger` ASC
            ",
            [
                $dateStart->value(),
                $dateEnd->value()
            ]
        );
        $objects = $this->generateCategorizedObjects($object);
        return $objects;
    }

    private function genRows(&$obj, &$keys)
    {
        return '<tr>' . implode('', array_map(fn ($key) => '<td>' . $obj->$key . '</td>', $keys)) . "</tr>\n";
    }

    private function generateObjects($listGroupPassenger)
    {
        return array_map(fn ($groupPassenger) => $this->generateObject($groupPassenger), $listGroupPassenger);
    }

    private function generateObject($groupPassenger)
    {
        $PassengerReviewAll = json_decode($groupPassenger->PassengerReviewAll_JSON);
        $groupProviderAll = json_decode($groupPassenger->GroupProvider_JSON);
        unset($groupPassenger->PassengerReviewAll_JSON);
        unset($groupPassenger->GroupProvider_JSON);
        $Global = $this->findGeneralScoreClean($PassengerReviewAll);
        $Guide = $this->findTypeProvider($PassengerReviewAll, 1);
        $SecondGuide = $this->findTypeProvider($PassengerReviewAll, 2);
        $Chef = $this->findTypeProvider($PassengerReviewAll, 3);
        $RestaurantMollepata = $this->findProviderName($PassengerReviewAll, 6, 'Mollepata');
        $RestaurantAguas = $this->findProviderName($PassengerReviewAll, 6, 'Aguas Calientes');
        $Transport = $this->findTypeProvider($PassengerReviewAll, 5);
        $Horseman = $this->findTypeProvider($PassengerReviewAll, 4);
        $CampsSkyCamp = $this->findProviderName($PassengerReviewAll, 15, 'Sky Camp');
        $CampsSkyView = $this->findProviderName($PassengerReviewAll, 15, 'Mountain Sky View');
        $CampsJungle = $this->findProviderName($PassengerReviewAll, 15, 'Jungle Domes');
        $CampsAndean = $this->findProviderName($PassengerReviewAll, 15, 'Andean Huts');
        $Hotel = $this->findTypeProvider($PassengerReviewAll, 8);
        $Recomend = $this->findQuestion($PassengerReviewAll, 16);
        $RecomendWhy = $this->findQuestion($PassengerReviewAll, 17);
        $Contact = $this->findQuestion($PassengerReviewAll, 18);
        $Moments = $this->findQuestion($PassengerReviewAll, 11);
        $Comments = $this->findQuestion($PassengerReviewAll, 13);

        $ProvGuide = $this->findTypeProvider($groupProviderAll, 1);
        $ProvSecondGuide = $this->findTypeProvider($groupProviderAll, 2);
        $ProvChef = $this->findTypeProvider($groupProviderAll, 3);
        $ProvRestaurantMollepata = $this->findProviderName($groupProviderAll, 6, 'Mollepata');
        $ProvRestaurantAguas = $this->findProviderName($groupProviderAll, 6, 'Aguas Calientes');
        $ProvTransport = $this->findTypeProvider($groupProviderAll, 5);
        $ProvHorseman = $this->findTypeProvider($groupProviderAll, 4);
        $ProvCampsSkyCamp = $this->findProviderName($groupProviderAll, 15, 'Sky Camp');
        $ProvCampsSkyView = $this->findProviderName($groupProviderAll, 15, 'Mountain Sky View');
        $ProvCampsJungle = $this->findProviderName($groupProviderAll, 15, 'Jungle Domes');
        $ProvCampsAndean = $this->findProviderName($groupProviderAll, 15, 'Andean Huts');
        $ProvHotel = $this->findTypeProvider($groupProviderAll, 8);

        $groupPassenger->Global_Score = $this->getAllFrom($Global, fn ($g) => $g->PassengerReview_Score);

        $groupPassenger->Guide_Name = $this->getAllFrom($Guide, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->Guide_Score = $this->getAllFrom($Guide, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->Guide_Comment = $this->getAllFrom($Guide, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->SecondGuide_Name = $this->getAllFrom($SecondGuide, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->SecondGuide_Score = $this->getAllFrom($SecondGuide, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->SecondGuide_Comment = $this->getAllFrom($SecondGuide, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Chef_Name = $this->getAllFrom($Chef, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->Chef_Score = $this->getAllFrom($Chef, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->Chef_Comment = $this->getAllFrom($Chef, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->RestaurantMollepata_Name = $this->getAllFrom($RestaurantMollepata, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->RestaurantMollepata_Score = $this->getAllFrom($RestaurantMollepata, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->RestaurantMollepata_Comment = $this->getAllFrom($RestaurantMollepata, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->RestaurantAguas_Name = $this->getAllFrom($RestaurantAguas, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->RestaurantAguas_Score = $this->getAllFrom($RestaurantAguas, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->RestaurantAguas_Comment = $this->getAllFrom($RestaurantAguas, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Transport_Name = $this->getAllFrom($Transport, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->Transport_Score = $this->getAllFrom($Transport, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->Transport_Comment = $this->getAllFrom($Transport, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Horseman_Name = $this->getAllFrom($Horseman, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->Horseman_Score = $this->getAllFrom($Horseman, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->Horseman_Comment = $this->getAllFrom($Horseman, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->CampsSkyCamp_Name = $this->getAllFrom($CampsSkyCamp, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->CampsSkyCamp_Score = $this->getAllFrom($CampsSkyCamp, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->CampsSkyCamp_Comment = $this->getAllFrom($CampsSkyCamp, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->CampsSkyView_Name = $this->getAllFrom($CampsSkyView, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->CampsSkyView_Score = $this->getAllFrom($CampsSkyView, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->CampsSkyView_Comment = $this->getAllFrom($CampsSkyView, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->CampsJungle_Name = $this->getAllFrom($CampsJungle, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->CampsJungle_Score = $this->getAllFrom($CampsJungle, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->CampsJungle_Comment = $this->getAllFrom($CampsJungle, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->CampsAndean_Name = $this->getAllFrom($CampsAndean, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->CampsAndean_Score = $this->getAllFrom($CampsAndean, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->CampsAndean_Comment = $this->getAllFrom($CampsAndean, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Hotel_Name = $this->getAllFrom($Hotel, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->Hotel_Score = $this->getAllFrom($Hotel, fn ($g) => $g->PassengerReview_Score);
        $groupPassenger->Hotel_Comment = $this->getAllFrom($Hotel, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Recomend_Comment = $this->getAllFrom($Recomend, fn ($g) => $this->getRecomend($g->PassengerReview_Values));
        $groupPassenger->RecomendWhy_Comment = $this->getAllFrom($RecomendWhy, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->Trip_Advisor = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 0));
        $groupPassenger->Google = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 1));
        $groupPassenger->Social_Network = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 2));
        $groupPassenger->Referencias = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 3));
        $groupPassenger->Otros = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 4));
        $groupPassenger->Moments_Comment = $this->getAllFrom($Moments, fn ($g) => $g->PassengerReview_Comment);
        $groupPassenger->Comments_Suggestions = $this->getAllFrom($Comments, fn ($g) => $g->PassengerReview_Comment);

        $groupPassenger->GPGuide_Name = $this->getAllFrom($ProvGuide, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPSecondGuide_Name = $this->getAllFrom($ProvSecondGuide, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPChef_Name = $this->getAllFrom($ProvChef, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPRestaurantMollepata_Name = $this->getAllFrom($ProvRestaurantMollepata, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPRestaurantAguas_Name = $this->getAllFrom($ProvRestaurantAguas, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPTransport_Name = $this->getAllFrom($ProvTransport, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPHorseman_Name = $this->getAllFrom($ProvHorseman, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPCampsSkyCamp_Name = $this->getAllFrom($ProvCampsSkyCamp, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPCampsSkyView_Name = $this->getAllFrom($ProvCampsSkyView, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPCampsJungle_Name = $this->getAllFrom($ProvCampsJungle, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPCampsAndean_Name = $this->getAllFrom($ProvCampsAndean, fn ($g) => $g->Provider_BusinessName);
        $groupPassenger->GPHotel_Name = $this->getAllFrom($ProvHotel, fn ($g) => $g->Provider_BusinessName);

        return $groupPassenger;
    }

    private function generateCategorizedObjects($listGroupPassenger)
    {
        return array_map(fn ($groupPassenger) => $this->generateCategorizedObject($groupPassenger), $listGroupPassenger);
    }

    private function generateCategorizedObject($groupPassenger)
    {
        $PassengerReviewAll = json_decode($groupPassenger->PassengerReviewAll_JSON);
        unset($groupPassenger->PassengerReviewAll_JSON);

        $Contact = $this->findQuestion($PassengerReviewAll, 18);

        $groupPassenger->Trip_Advisor = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 0));
        $groupPassenger->Google = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 1));
        $groupPassenger->Social_Network = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 2));
        $groupPassenger->Referencias = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 3));
        $groupPassenger->Otros = $this->getAllFrom($Contact, fn ($g) => $this->getContact($g->PassengerReview_Values, 4));

        return $groupPassenger;
    }

    private function getContact($values, $index)
    {
        $contact = json_decode($values);
        if (!isset($contact[$index]->selected)) {
            return '';
        }
        if ($contact[$index]->selected) {
            return 'Sí';
        }
        return '';
    }

    private function getRecomend($values)
    {
        $data = json_decode($values);
        if ($data[0]->selected) {
            return 'Sí';
        }
        if ($data[1]->selected) {
            return 'No';
        }
        return '';
    }

    private function getAllFrom($reviewArray, $callable)
    {
        return implode(',', array_map($callable, $reviewArray));
    }

    private function findGeneralScoreClean($reviewAll)
    {
        $find = [];
        foreach ($reviewAll as $value) {
            if ($value->Id_TypeProvider == null && $value->Question_General == 2 && in_array($value->Question_Type, [1, 3, 8])) {
                $find[] = $value;
            }
        }
        return $find;
    }

    private function findQuestion($reviewAll, $idQuestion)
    {
        $find = [];
        foreach ($reviewAll as $value) {
            if ($value->Id_Question == $idQuestion) {
                $find[] = $value;
            }
        }
        return $find;
    }

    private function findTypeProvider($reviewAll, $idTypeProvider)
    {
        $find = [];
        foreach ($reviewAll as $value) {
            if ($value->Id_TypeProvider == $idTypeProvider) {
                $find[] = $value;
            }
        }
        return $find;
    }

    private function findProviderName($reviewAll, $idTypeProvider, $ProviderName)
    {
        $find = [];
        foreach ($reviewAll as $value) {
            if ($value->Id_TypeProvider == $idTypeProvider && str_contains($value->Provider_BusinessName, $ProviderName)) {
                $find[] = $value;
            }
        }
        return $find;
    }
}
