<?php

namespace Tests\Http\Controllers\CsvController\CsvCostCalc;

use App\Http\Controllers\CsvController\CsvCostCalc\CsvAgentCost;
use App\Http\Controllers\CsvController\CsvCostCalc\CsvMinuteCostCalc;
use PHPUnit\Framework\TestCase;
use RuntimeException;

class CsvAgentCostTest extends TestCase
{
    protected function setUp(): void
    {
        $this->csv_agent_cost = new CsvAgentCost();
        $this->mockCsvMinuteCostCalc = $this->createMock(CsvMinuteCostCalc::class);
        $this->csv_agent_cost->CsvMinuteCostCalc = $this->mockCsvMinuteCostCalc;
        // Set a value for internal_percentage_to_deduct
        $this->csv_agent_cost->internal_percentage_to_deduct = 10; // Example percentage
    }

    public function testPrepareAgentsColumnsWithValidInput()
    {
        $array = [];
        $company_agents = ['Agent1', 'Agent2'];

        $expected = [
            'Agent1' => '',
            'Agent1 costo' => 0,
            'Agent2' => '',
            'Agent2 costo' => 0,
        ];

        $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents);
        $this->assertEquals($expected, $result);
    }

    /**
     * Test the prepare_agents_columns function with an empty company_agents array.
     */
    public function testPrepareAgentsColumnsWithEmptyAgents()
    {
        $array = ['existing_key' => 'existing_value'];
        $company_agents = [];

        $expected = [
            'existing_key' => 'existing_value',
        ];

        $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents);
        $this->assertEquals($expected, $result);
    }

    /**
     * Test the prepare_agents_columns function with pre-existing keys.
     */
    public function testPrepareAgentsColumnsWithPreExistingKeys()
    {
        $array = [
            'Request By' => 'some_value',
            'Priority' => 5,
        ];
        $company_agents = ['Agent1', 'Agent2'];

        $expected = [
            'Request By' => 'some_value',
            'Priority' => 5,
            'Agent1' => '',
            'Agent1 costo' => 0,
            'Agent2' => '',
            'Agent2 costo' => 0,
        ];

        $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents);
        $this->assertEquals($expected, $result);
    }

    /**
     * Test with a basic input.
     */
    public function testAgentCostCalcBasicInput()
    {
        $minute_cost = 5.15552; // Cost per minute
        $array = [];
        $agents_time = [
            'Agent A' => 7200, // 2 hours
            'Agent B' => 10800, // 3 hours
        ];

        // Ricordarsi che all'esecuzione della funzione, è gia stata dedotta la percentuale interna
        $expected = [
            'Agent A' => '02:00:00',
            'Agent A costo' =>  618.67, // 120 minutes * 5.0
            'Agent B' => '03:00:00',
            'Agent B costo' => 928.0, // 180 minutes * 5.0
        ];

        $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost);

        $this->assertEquals($expected, $result);
    }

    /**
     * Test with zero agent time.
     */
    public function testAgentCostCalcZeroAgentTime()
    {
        $array = [];
        $agents_time = [
            'Agent C' => 0, // 0 hours
        ];
        $minute_cost = 5.0;

        $expected = [
            'Agent C' => '00:00:00',
            'Agent C costo' => 0.0,
        ];

        $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost);

        $this->assertEquals($expected, $result);
    }

    /**
     * Test with different minute costs.
     */
    public function testAgentCostCalcDifferentMinuteCosts()
    {
        $array = [];
        $agents_time = [
            'Agent E' => 14400, // 4 hours
        ];
        $minute_cost = 10.0; // Higher cost per minute

        $expected = [
            'Agent E' => '04:00:00',
            'Agent E costo' => 2400.0, // 240 minutes * 10.0
        ];

        $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost);

        $this->assertEquals($expected, $result);
    }

    public function testSelectCorrectCostCalculatesCostCorrectly()
    {
        // percentuale dedotta impostata nel setup di questa classe
        // Costo orario per cliente con issue high, 75.5€/h
        $array = [
            'Progetto' => 'Progetto Test',
            '#' => 31,
            'Titolo' => 'Titolo test',
            'URL' => 'https://git.example.net/Cliente/ProgettoTest/issues/31',
            'Aperto_il' => '2024-05-30T15:53:58+02:00',
            'Chiuso_il' => '2024-06-05T10:40:30+02:00',
            'Etichette' => 'Kind/Bug,Priority/High,RequestBy/Cliente,Status/Resolved,',
            'Kind' => 'Kind/Bug',
            'Request By' => 'RequestBy/Client',
            'Priority' => 'Priority/High',
            'Tempo totale' => '00:10:00',
            'Costo totale' => 12.6,
        ];
        $company_agents = ['agentTest']; // Populate as necessary
        $agents_time = ['agentTest' => 600]; // Populate as necessary

        //Valori presi dalla classe di test di CsvMinuteCostCalcTest
        $this->mockCsvMinuteCostCalc
            ->expects($this->once())
            ->method('select_correct_cost')
            ->with('RequestBy/Client', 'Priority/High')
            ->willReturn(1.26); // Mocked return value

        $expected_result = $array;
        $expected_result = array_merge($array, [
            'agentTest' => '00:10:00',
            'agentTest costo' => 11.34
        ]);

        // Call the method being tested
        $result = $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time);

        // Assert the expected outcome
        $this->assertEquals($expected_result, $result);
    }

    public function testInternalPercentageSetTo0()
    {
        // Set internal_percentage_to_deduct to 0 to trigger the exception
        $this->csv_agent_cost->internal_percentage_to_deduct = 0;

        // percentuale dedotta impostata nel setup
        // Costo orario per cliente con issue high, 75.5€/h
        $array = [
            'Progetto' => 'Progetto Test',
            '#' => 31,
            'Titolo' => 'Titolo test',
            'URL' => 'https://git.example.net/Cliente/ProgettoTest/issues/31',
            'Aperto_il' => '2024-05-30T15:53:58+02:00',
            'Chiuso_il' => '2024-06-05T10:40:30+02:00',
            'Etichette' => 'Kind/Bug,Priority/High,RequestBy/Cliente,Status/Resolved,',
            'Kind' => 'Kind/Bug',
            'Request By' => 'RequestBy/Client',
            'Priority' => 'Priority/High',
            'Tempo totale' => '00:10:00',
            'Costo totale' => 12.6,
        ];
        $company_agents = ['agentTest']; // Populate as necessary
        $agents_time = ['agentTest' => 600]; // Populate as necessary

        //Valori presi dalla classe di test di CsvMinuteCostCalcTest
        $this->mockCsvMinuteCostCalc
            ->expects($this->once())
            ->method('select_correct_cost')
            ->with('RequestBy/Client', 'Priority/High')
            ->willReturn(1.26); // Mocked return value

        $expected_result = $array;
        $expected_result = array_merge($array, [
            'agentTest' => '00:10:00',
            'agentTest costo' => 12.6
        ]);

        // Call the method being tested
        $result = $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time);

        // Assert the expected outcome
        $this->assertEquals($expected_result, $result);
    }

    public function testInternalPercentageSetNull()
    {
        // Imposta a null così da far lanciare l'errore
        $this->csv_agent_cost->internal_percentage_to_deduct = null;

        $this->expectException(RuntimeException::class);

        // Prepare input data
        $array = [
            'Request By' => 'Agent A',
            'Priority' => 'High'
        ];
        $company_agents = []; // Populate as necessary
        $agents_time = []; // Populate as necessary

        // Call the method being tested
        $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time);
    }
}