<?php

namespace App\Imports;

use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\SkipsOnError;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Validators\Failure;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use Throwable;

abstract class BaseImport implements
    ToCollection,
    WithHeadingRow,
    WithValidation,
    WithChunkReading,
    SkipsOnError,
    SkipsOnFailure,
    SkipsEmptyRows
{
    protected array $errors = [];
    protected array $failures = [];
    protected int $successCount = 0;
    protected int $skipCount = 0;
    protected bool $updateExisting = false;
    protected bool $dryRun = false;

    public function __construct(bool $updateExisting = false, bool $dryRun = false)
    {
        $this->updateExisting = $updateExisting;
        $this->dryRun = $dryRun;
    }

    abstract public function collection(Collection $collection);

    abstract public function rules(): array;

    public function chunkSize(): int
    {
        return 100;
    }

    public function onError(Throwable $e)
    {
        $this->errors[] = $e->getMessage();
    }

    public function onFailure(Failure ...$failures)
    {
        foreach ($failures as $failure) {
            $this->failures[] = [
                'row' => $failure->row(),
                'attribute' => $failure->attribute(),
                'errors' => $failure->errors(),
                'values' => $failure->values(),
            ];
        }
    }

    public function getResults(): array
    {
        return [
            'success' => $this->successCount,
            'skipped' => $this->skipCount,
            'errors' => $this->errors,
            'failures' => $this->failures,
        ];
    }

    /**
     * Parse translatable field from row data
     */
    protected function parseTranslatable(array $row, string $field): array
    {
        return [
            'en' => trim($row["{$field}_en"] ?? $row[$field] ?? ''),
            'ar' => trim($row["{$field}_ar"] ?? ''),
        ];
    }

    /**
     * Parse status field to integer
     */
    protected function parseStatus($value): int
    {
        if (is_numeric($value)) {
            return (int) $value;
        }

        if (is_bool($value)) {
            return $value ? 1 : 0;
        }

        $value = strtolower(trim((string) $value));

        return in_array($value, ['active', 'yes', '1', 'true', 'نشط']) ? 1 : 0;
    }

    /**
     * Parse boolean field
     */
    protected function parseBoolean($value): bool
    {
        if (is_bool($value)) {
            return $value;
        }

        if (is_numeric($value)) {
            return (bool) $value;
        }

        $value = strtolower(trim((string) $value));

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

    /**
     * Parse numeric field with default
     */
    protected function parseNumeric($value, $default = null): ?float
    {
        if ($value === null || $value === '') {
            return $default;
        }

        return is_numeric($value) ? (float) $value : $default;
    }

    /**
     * Parse integer field with default
     */
    protected function parseInt($value, $default = null): ?int
    {
        if ($value === null || $value === '') {
            return $default;
        }

        return is_numeric($value) ? (int) $value : $default;
    }

    /**
     * Download image from URL and store it
     */
    protected function downloadImage(string $url, string $folder): ?string
    {
        if (empty($url)) {
            return null;
        }

        try {
            $context = stream_context_create([
                'http' => [
                    'timeout' => 30,
                    'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
                ],
                'ssl' => [
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                ]
            ]);

            $contents = @file_get_contents($url, false, $context);

            if ($contents === false) {
                return null;
            }

            $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'png';
            $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'];

            if (!in_array(strtolower($extension), $allowedExtensions)) {
                $extension = 'png';
            }

            $filename = Str::uuid() . '.' . $extension;
            $path = $folder . '/' . $filename;

            Storage::disk('public')->put($path, $contents);

            return $path;
        } catch (\Exception $e) {
            $this->errors[] = "Failed to download image: {$url} - " . $e->getMessage();
            return null;
        }
    }

    /**
     * Clean string value
     */
    protected function cleanString($value): ?string
    {
        if ($value === null || $value === '') {
            return null;
        }

        return trim((string) $value);
    }

    /**
     * Check if row has required data (not empty)
     */
    protected function isEmptyRow(array $row): bool
    {
        foreach ($row as $value) {
            if (!empty($value)) {
                return false;
            }
        }

        return true;
    }
}
