<?php

namespace App\Filament\AssociationAdmin\Imports;

use App\Enums\LicenseStatus;
use App\Models\Center;
use App\Models\City;
use App\Models\State;
use App\Models\StationLicense;
use App\Models\WellLicense;
use EightyNine\ExcelImport\EnhancedDefaultImport;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;

class AssociationStationLicenseExcelImport extends EnhancedDefaultImport
{
    protected function beforeCollection(Collection $collection): void
    {
        // Validate required headers
        $requiredHeaders = [
            'station_name',
            'state',
            'city',
            'center',
            'lat',
            'lng',
            'site_area',
            'design_capacity',
            'operation_start_date',
            'has_environmental_permit',
            'has_evaporation_ponds',
            'evaporation_ponds_count',
            'evaporation_ponds_area',
            'well_licenses',
        ];

        $this->validateHeaders($requiredHeaders, $collection);

        // Check if collection is not empty
        if ($collection->isEmpty()) {
            $this->stopImportWithError(__('station_license.import_no_data'));
        }

        // Validate that user has an association
        $user = Auth::user();
        if (! $user || ! $user->association_id) {
            $this->stopImportWithError(__('station_license.import_no_association'));
        }
    }

    protected function beforeCreateRecord(array $data, $row): void
    {
        // Validate state exists
        if (isset($data['state'])) {
            $state = State::where('name', $data['state'])->first();
            if (! $state) {
                $this->stopImportWithError(
                    __('station_license.import_state_not_found', ['name' => $data['state']])
                );
            }
        }

        // Validate city exists and belongs to state
        if (isset($data['city']) && isset($state)) {
            $city = City::where('name', $data['city'])
                ->where('state_id', $state->id)
                ->first();
            if (! $city) {
                $this->stopImportWithError(
                    __('station_license.import_city_not_found', ['name' => $data['city'], 'state' => $state->name])
                );
            }
        }

        // Validate center exists and belongs to city
        if (isset($data['center']) && isset($city)) {
            $center = Center::where('name', $data['center'])
                ->where('city_id', $city->id)
                ->first();
            if (! $center) {
                $this->stopImportWithError(
                    __('station_license.import_center_not_found', ['name' => $data['center'], 'city' => $city->name])
                );
            }
        }

        // Check for duplicate station name within the same association
        $user = Auth::user();
        if (isset($data['station_name']) && $user && $user->association_id) {
            $exists = StationLicense::where('station_name', $data['station_name'])
                ->where('association_id', $user->association_id)
                ->exists();

            if ($exists) {
                $this->stopImportWithWarning(
                    __('station_license.import_duplicate_station', ['name' => $data['station_name'], 'association' => $user->association->name ?? ''])
                );
            }
        }

        // Validate well licenses if provided
        if (isset($data['well_licenses']) && ! empty($data['well_licenses']) && $user && $user->association_id) {
            $wellLicenseNames = array_map('trim', explode(',', $data['well_licenses']));

            foreach ($wellLicenseNames as $wellName) {
                $wellLicense = WellLicense::where('well_name', $wellName)
                    ->where('association_id', $user->association_id)
                    ->first();

                if (! $wellLicense) {
                    $this->stopImportWithError(
                        __('station_license.import_well_license_not_found', ['name' => $wellName, 'association' => $user->association->name ?? ''])
                    );
                }
            }
        }
    }

    public function collection(Collection $collection)
    {
        $user = Auth::user();
        $associationId = $user->association_id;

        foreach ($collection as $row) {
            $data = $this->prepareRowData($row);

            $this->beforeCreateRecord($data, $row);

            // Resolve relationships
            $state = State::where('name', $data['state'])->first();
            $city = City::where('name', $data['city'])->where('state_id', $state->id)->first();
            $center = Center::where('name', $data['center'])->where('city_id', $city->id)->first();

            // Parse date
            $operationStartDate = null;
            if (! empty($data['operation_start_date'])) {
                try {
                    $operationStartDate = \Carbon\Carbon::parse($data['operation_start_date'])->format('Y-m-d');
                } catch (\Exception $e) {
                    $operationStartDate = null;
                }
            }

            // Create the station license
            $stationLicense = StationLicense::create([
                'association_id' => $associationId,
                'station_name' => $data['station_name'],
                'state_id' => $state->id,
                'city_id' => $city->id,
                'center_id' => $center->id,
                'lat' => $data['lat'],
                'lng' => $data['lng'],
                'site_area' => $data['site_area'],
                'design_capacity' => $data['design_capacity'],
                'operation_start_date' => $operationStartDate,
                'has_environmental_permit' => $this->parseBoolean($data['has_environmental_permit'] ?? false),
                'has_evaporation_ponds' => $this->parseBoolean($data['has_evaporation_ponds'] ?? false),
                'evaporation_ponds_count' => $data['evaporation_ponds_count'] ?? null,
                'evaporation_ponds_area' => $data['evaporation_ponds_area'] ?? null,
                'status' => LicenseStatus::PENDING_REQUIREMENTS,
                'created_by' => Auth::id(),
            ]);

            // Attach well licenses if provided
            if (! empty($data['well_licenses'])) {
                $wellLicenseNames = array_map('trim', explode(',', $data['well_licenses']));
                $wellLicenseIds = WellLicense::where('association_id', $associationId)
                    ->whereIn('well_name', $wellLicenseNames)
                    ->pluck('id')
                    ->toArray();

                if (! empty($wellLicenseIds)) {
                    $stationLicense->wellLicenses()->attach($wellLicenseIds);
                }
            }

            $this->afterCreateRecord($data, $row);
        }
    }

    protected function prepareRowData($row): array
    {
        return [
            'station_name' => $row['station_name'] ?? null,
            'state' => $row['state'] ?? null,
            'city' => $row['city'] ?? null,
            'center' => $row['center'] ?? null,
            'lat' => $row['lat'] ?? null,
            'lng' => $row['lng'] ?? null,
            'site_area' => $row['site_area'] ?? null,
            'design_capacity' => $row['design_capacity'] ?? null,
            'operation_start_date' => $row['operation_start_date'] ?? null,
            'has_environmental_permit' => $row['has_environmental_permit'] ?? false,
            'has_evaporation_ponds' => $row['has_evaporation_ponds'] ?? false,
            'evaporation_ponds_count' => $row['evaporation_ponds_count'] ?? null,
            'evaporation_ponds_area' => $row['evaporation_ponds_area'] ?? null,
            'well_licenses' => $row['well_licenses'] ?? null,
        ];
    }

    protected function parseBoolean($value): bool
    {
        if (is_bool($value)) {
            return $value;
        }

        if (is_string($value)) {
            $value = strtolower(trim($value));

            return in_array($value, ['1', 'true', 'yes', 'y', 'نعم'], true);
        }

        return (bool) $value;
    }

    protected function afterCollection(Collection $collection): void
    {
        $count = $collection->count();
        $this->stopImportWithSuccess(
            __('station_license.import_success', ['count' => $count])
        );
    }
}
