<?php

namespace Tests\Feature;

use App\Models\Association;
use App\Models\DonorFinancialPortfolio;
use App\Models\Order;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class UpdateOrderDatesFromCsvTest extends TestCase
{
    use RefreshDatabase;

    protected Association $association;

    protected DonorFinancialPortfolio $donorPortfolio;

    protected User $adminUser;

    protected Order $order1;

    protected Order $order2;

    protected function setUp(): void
    {
        parent::setUp();

        // Create test data
        $this->association = Association::factory()->create(['name' => 'جمعية البر الخيرية']);
        $this->donorPortfolio = DonorFinancialPortfolio::factory()->create(['name' => 'محفظة المانح الأول']);
        $this->adminUser = User::factory()->create(['email' => 'admin@sekaya.com']);

        // Create test orders
        $this->order1 = Order::factory()->create([
            'association_id' => $this->association->id,
            'type' => Order::TYPE_STATION,
            'number_of_families' => 100,
            'created_by' => $this->adminUser->id,
            'created_at' => Carbon::now()->subDays(30), // Old date
        ]);

        $this->order2 = Order::factory()->create([
            'association_id' => $this->association->id,
            'type' => Order::TYPE_TANKER,
            'number_of_families' => 50,
            'created_by' => $this->adminUser->id,
            'created_at' => Carbon::now()->subDays(25), // Old date
        ]);

        // Link orders to donor portfolio
        $this->order1->donorFinancialPortfolios()->attach($this->donorPortfolio->id);
        $this->order2->donorFinancialPortfolios()->attach($this->donorPortfolio->id);
    }

    public function test_updates_order_dates_successfully()
    {
        // Create test CSV content
        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع;تاريخ الاعتماد\n";
        $csvContent .= "جمعية البر الخيرية;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23;27/10/22\n";
        $csvContent .= 'جمعية البر الخيرية;محفظة المانح الأول;صهاريج;50;الرياض;مركز الملك عبدالله;3;500;25000;01/02/23;15/11/22';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        // Run the command
        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile])
            ->expectsOutput('Starting order date updates from CSV...')
            ->expectsOutput('Updated: 2 orders')
            ->assertExitCode(0);

        // Verify the dates were updated
        $this->order1->refresh();
        $this->order2->refresh();

        $expectedDate1 = Carbon::createFromDate(2022, 10, 27)->startOfDay();
        $expectedDate2 = Carbon::createFromDate(2022, 11, 15)->startOfDay();

        $this->assertEquals($expectedDate1->format('Y-m-d'), $this->order1->created_at->format('Y-m-d'));
        $this->assertEquals($expectedDate2->format('Y-m-d'), $this->order2->created_at->format('Y-m-d'));

        unlink($tempFile);
    }

    public function test_dry_run_mode_does_not_update()
    {
        $originalDate = $this->order1->created_at;

        // Create test CSV content
        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع;تاريخ الاعتماد\n";
        $csvContent .= 'جمعية البر الخيرية;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23;27/10/22';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        // Run the command with dry-run
        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile, '--dry-run' => true])
            ->expectsOutput('=== DRY RUN MODE - No changes will be applied ===')
            ->expectsOutput('Would update: 1 orders')
            ->assertExitCode(0);

        // Verify the date was NOT updated
        $this->order1->refresh();
        $this->assertEquals($originalDate->format('Y-m-d H:i:s'), $this->order1->created_at->format('Y-m-d H:i:s'));

        unlink($tempFile);
    }

    public function test_handles_multiple_matches_safely()
    {
        // Create a duplicate order with same criteria
        $duplicateOrder = Order::factory()->create([
            'association_id' => $this->association->id,
            'type' => Order::TYPE_STATION,
            'number_of_families' => 100,
            'created_by' => $this->adminUser->id,
        ]);
        $duplicateOrder->donorFinancialPortfolios()->attach($this->donorPortfolio->id);

        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع;تاريخ الاعتماد\n";
        $csvContent .= 'جمعية البر الخيرية;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23;27/10/22';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile])
            ->expectsOutput('Multiple matches (skipped): 1 rows')
            ->expectsOutput('Updated: 0 orders')
            ->assertExitCode(0);

        unlink($tempFile);
    }

    public function test_handles_no_matches()
    {
        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع;تاريخ الاعتماد\n";
        $csvContent .= 'جمعية غير موجودة;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23;27/10/22';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile])
            ->expectsOutput('No matches found: 1 rows')
            ->expectsOutput('Updated: 0 orders')
            ->assertExitCode(0);

        unlink($tempFile);
    }

    public function test_validates_date_format()
    {
        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع;تاريخ الاعتماد\n";
        $csvContent .= 'جمعية البر الخيرية;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23;invalid-date';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile])
            ->expectsOutput('Skipped (invalid data): 1 rows')
            ->expectsOutput('Updated: 0 orders')
            ->assertExitCode(0);

        unlink($tempFile);
    }

    public function test_requires_approval_date_header()
    {
        // CSV without the required date header
        $csvContent = "اسم الجهة;محفظة المشاريع السابقة;المشروع المعتمد; عدد الأسر المستفيدة ;المنطقة;المركز;العدد;السعة;قيمة المشروع;تاريخ بداية المشروع\n";
        $csvContent .= 'جمعية البر الخيرية;محفظة المانح الأول;محطة;100;الرياض;مركز الملك عبدالله;5;1000;50000;01/01/23';

        $tempFile = tempnam(sys_get_temp_dir(), 'test_orders_');
        file_put_contents($tempFile, $csvContent);

        $this->artisan('update:order-dates-from-csv', ['file' => $tempFile])
            ->expectsOutput("Failed to process CSV: Required header 'تاريخ الاعتماد' not found in CSV")
            ->assertExitCode(1);

        unlink($tempFile);
    }
}
