<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Bundle\ChillPersonBundle\Tests\Exporters;

use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Service\SocialWork\SocialActionCSVExportService;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * @internal
 *
 * @coversNothing
 */
class SocialActionCsvExporterTest extends TestCase
{
    public function testGenerateCsv(): void
    {
        $translator = $this->createMock(TranslatorInterface::class);
        $translator->method('trans')->willReturnArgument(0);
        $socialIssueRender = $this->createMock(SocialIssueRender::class);
        $socialIssueRender->method('renderString')->willReturnCallback(static fn (SocialIssue $socialIssue) => $socialIssue->getTitle()['fr'] ?? '');
        $socialActionRender = $this->createMock(SocialActionRender::class);
        $socialActionRender->method('renderString')->willReturnCallback(static fn (SocialAction $socialAction) => $socialAction->getTitle()['fr'] ?? '');
        $stringHelper = $this->createMock(TranslatableStringHelperInterface::class);
        $stringHelper->method('localize')
            ->willReturnCallback(static fn (array $messages) => $messages['fr'] ?? 'not found');

        $exporter = new SocialActionCSVExportService($socialIssueRender, $socialActionRender, $stringHelper, $translator);

        // Mock social issue

        // Création d'une instance réelle de SocialIssue
        $socialIssue = new SocialIssue();
        $socialIssue->setTitle(['fr' => 'Issue Title']); // Exemple de définition d'une propriété

        // Création d'une instance réelle de SocialAction sans objectifs ni résultats
        $actionWithoutGoalsOrResults = new SocialAction();
        $actionWithoutGoalsOrResults->setIssue($socialIssue);
        $actionWithoutGoalsOrResults->setDesactivationDate(new \DateTime('2025-05-21'));
        $actionWithoutGoalsOrResults->setTitle(['fr' => 'Action without goals or results']);

        // Création d'une instance réelle de SocialAction avec des objectifs et des résultats
        $goalWithResult = new Goal();
        $resultWithAction = new Result();
        $goalWithResult->addResult($resultWithAction);

        $actionWithGoalsAndResults = new SocialAction();
        $actionWithGoalsAndResults->setIssue($socialIssue);
        $actionWithGoalsAndResults->setDesactivationDate(new \DateTime('2025-05-21'));
        $actionWithGoalsAndResults->setTitle(['fr' => 'Action with goals and results']);
        $actionWithGoalsAndResults->addGoal($goalWithResult);

        // Création d'une instance réelle de SocialAction avec des objectifs mais sans résultats
        $goalWithoutResult = new Goal();
        $actionWithGoalsNoResults = new SocialAction();
        $actionWithGoalsNoResults->setIssue($socialIssue);
        $actionWithGoalsNoResults->setDesactivationDate(new \DateTime('2025-05-21'));
        $actionWithGoalsNoResults->setTitle(['fr' => 'Action with goals and no results']);
        $actionWithGoalsNoResults->addGoal($goalWithoutResult);

        // Création d'une instance réelle de SocialAction avec des résultats mais sans objectifs
        $resultWithNoAction = new Result();
        $resultWithNoAction->setTitle(['fr' => 'Result without objectives']);
        $actionWithResultsNoGoals = new SocialAction();
        $actionWithResultsNoGoals->setIssue($socialIssue);
        $actionWithResultsNoGoals->setDesactivationDate(new \DateTime('2025-05-21'));
        $actionWithResultsNoGoals->setTitle(['fr' => 'Action with results and no goals']);
        $actionWithResultsNoGoals->addResult($resultWithNoAction);

        // generate
        $csv = $exporter->generateCsv([$actionWithGoalsAndResults, $actionWithoutGoalsOrResults,
            $actionWithGoalsNoResults, $actionWithResultsNoGoals]);
        $content = $csv->toString();

        // Assert CSV contains expected values
        $this->assertStringContainsString('Action without goals or results', $content);
        $this->assertStringContainsString('Action with goals and results', $content);
        $this->assertStringContainsString('Action with goals and no results', $content);
        $this->assertStringContainsString('Action with results and no goals', $content);

        self::assertEquals(<<<'CSV'
        export.social_action_list.action_id,export.social_action_list.social_issue_id,export.social_action_list.problematique_label,export.social_action_list.desactivation_date,export.social_action_list.social_issue_ordering,export.social_action_list.action_label,export.social_action_list.action_ordering,export.social_action_list.goal_label,export.social_action_list.goal_id,export.social_action_list.goal_result_label,export.social_action_list.goal_result_id,export.social_action_list.result_without_goal_label,export.social_action_list.result_without_goal_id,export.social_action_list.evaluation_title,export.social_action_list.evaluation_id,export.social_action_list.evaluation_url,export.social_action_list.evaluation_delay_month,export.social_action_list.evaluation_delay_week,export.social_action_list.evaluation_delay_day
        ,,"Issue Title",2025-05-21,0,"Action with goals and results",0,"not found",,"not found",,,,,,,,,
        ,,"Issue Title",2025-05-21,0,"Action without goals or results",0,,,,,,,,,,,,
        ,,"Issue Title",2025-05-21,0,"Action with goals and no results",0,"not found",,,,,,,,,,,
        ,,"Issue Title",2025-05-21,0,"Action with results and no goals",0,,,,,"Result without objectives",,,,,,,

        CSV, $content);
    }
}
