<?php

namespace Database\Seeders;

use App\Models\WaterSource;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\File;

class WaterSourceSeeder extends Seeder
{
    /**
     * Run the database seeder.
     */
    public function run(): void
    {
        $csvFile = database_path('seeders/files/water_sources_data.csv');

        // Check if file exists
        if (! File::exists($csvFile)) {
            $this->command->error("CSV file not found: {$csvFile}");

            return;
        }

        $this->command->info("Starting water sources import from: {$csvFile}");

        try {
            // Read and process CSV
            $data = $this->readCsvFile($csvFile);

            if (empty($data)) {
                $this->command->error('No data found in CSV file or invalid format');

                return;
            }

            $this->command->info('Found '.count($data).' records in CSV');

            // Process water sources
            $this->processWaterSources($data);

            $this->command->info('Water sources import completed successfully!');
        } catch (\Exception $e) {
            $this->command->error('Error processing CSV: '.$e->getMessage());
        }
    }

    /**
     * Read CSV file and return data array
     */
    private function readCsvFile($filePath)
    {
        $data = [];
        $file = fopen($filePath, 'r');

        if (! $file) {
            throw new \Exception('Cannot open CSV file');
        }

        // Read header line
        $header = fgetcsv($file, 0, ',');

        if (! $header || count($header) < 3) {
            fclose($file);
            throw new \Exception('Invalid CSV header format. Expected: water_source,x_coordinate,y_coordinate');
        }

        // Validate headers
        $expectedHeaders = ['water_source', 'x_coordinate', 'y_coordinate'];
        $headerMap = [];

        foreach ($expectedHeaders as $expectedHeader) {
            $index = array_search($expectedHeader, array_map('trim', $header));
            if ($index === false) {
                fclose($file);
                throw new \Exception("Missing required header: {$expectedHeader}");
            }
            $headerMap[$expectedHeader] = $index;
        }

        // Read data lines
        $lineNumber = 1;
        while (($row = fgetcsv($file, 0, ',')) !== false) {
            $lineNumber++;

            if (count($row) < 3) {
                $this->command->warn("Skipping line {$lineNumber}: insufficient columns");

                continue;
            }

            $waterSourceName = trim($row[$headerMap['water_source']]);
            $xCoordinate = trim($row[$headerMap['x_coordinate']]);
            $yCoordinate = trim($row[$headerMap['y_coordinate']]);

            // Validate data
            if (empty($waterSourceName)) {
                $this->command->warn("Skipping line {$lineNumber}: empty water source name");

                continue;
            }

            if (! is_numeric($xCoordinate) || ! is_numeric($yCoordinate)) {
                $this->command->warn("Skipping line {$lineNumber}: invalid coordinates ({$xCoordinate}, {$yCoordinate})");

                continue;
            }

            // Convert coordinates to proper decimal format
            $lng = (float) $xCoordinate;
            $lat = (float) $yCoordinate;

            // Basic coordinate validation (adjust ranges as needed for your region)
            if ($lng < -180 || $lng > 180 || $lat < -90 || $lat > 90) {
                $this->command->warn("Skipping line {$lineNumber}: coordinates out of valid range ({$lng}, {$lat})");

                continue;
            }

            $data[] = [
                'name' => $waterSourceName,
                'lng' => $lng,
                'lat' => $lat,
            ];
        }

        fclose($file);

        return $data;
    }

    /**
     * Process and create Water Sources
     */
    private function processWaterSources($data)
    {
        $this->command->info('Processing Water Sources...');

        $createdCount = 0;
        $errorCount = 0;

        foreach ($data as $waterSourceData) {
            try {
                // Create new water source
                WaterSource::create($waterSourceData);
                $createdCount++;
                $this->command->line("Created: {$waterSourceData['name']} ({$waterSourceData['lat']}, {$waterSourceData['lng']})");
            } catch (\Exception $e) {
                $errorCount++;
                $this->command->error("Error processing {$waterSourceData['name']}: ".$e->getMessage());
            }
        }

        $this->command->info("Water Sources processed - Created: {$createdCount}, Errors: {$errorCount}");
    }
}
