<?php

namespace App\Imports;

use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Exception;

abstract class BaseImport implements ToModel, WithHeadingRow, WithValidation, WithBatchInserts, WithChunkReading
{
    protected $results = [
        'success_count' => 0,
        'error_count' => 0,
        'errors' => [],
        'updated_count' => 0,
        'skipped_count' => 0,
    ];

    protected $options = [];
    protected $modelClass;
    protected $updateExisting = false;
    protected $skipDuplicates = true;

    public function __construct($options = [])
    {
        $this->options = $options;
        $this->updateExisting = $options['update_existing'] ?? false;
        $this->skipDuplicates = $options['skip_duplicates'] ?? true;
    }

    abstract public function model(array $row);

    abstract public function rules(): array;

    abstract public function customValidationMessages(): array;

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

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

    public function withValidation($validator)
    {
        if ($validator->fails()) {
            $this->results['error_count']++;
            $this->results['errors'][] = [
                'row' => $validator->getData()['row'] ?? 'unknown',
                'errors' => $validator->errors()->toArray(),
            ];
        }
    }

    public function getResults()
    {
        return $this->results;
    }

    protected function logError($message, $context = [])
    {
        Log::error($message, $context);
    }

    protected function logInfo($message, $context = [])
    {
        Log::info($message, $context);
    }

    protected function handleDuplicate($row, $identifierField)
    {
        if ($this->skipDuplicates) {
            $this->results['skipped_count']++;
            return true;
        }

        if ($this->updateExisting) {
            $this->updateRecord($row, $identifierField);
            $this->results['updated_count']++;
            return true;
        }

        return false;
    }

    protected function updateRecord($row, $identifierField)
    {
        $identifier = $row[$identifierField] ?? null;
        
        if (!$identifier) {
            return false;
        }

        $model = $this->modelClass::where($identifierField, $identifier)->first();
        
        if ($model) {
            $model->update($row);
            return true;
        }

        return false;
    }

    protected function resolveRelationship($value, $modelClass, $field = 'libelle')
    {
        if (empty($value)) {
            return null;
        }

        $model = $modelClass::where($field, $value)->first();
        
        return $model ? $model->id : null;
    }

    protected function formatDate($date, $format = 'Y-m-d')
    {
        if (empty($date)) {
            return null;
        }

        try {
            $dateObj = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date);
            return $dateObj->format($format);
        } catch (\Exception $e) {
            try {
                $dateObj = \DateTime::createFromFormat('d/m/Y', $date);
                return $dateObj ? $dateObj->format($format) : null;
            } catch (\Exception $e2) {
                return null;
            }
        }
    }

    protected function normalizeText($text)
    {
        if (empty($text)) {
            return null;
        }

        return trim(preg_replace('/\s+/', ' ', $text));
    }

    protected function validateRow($row)
    {
        $validator = Validator::make($row, $this->rules(), $this->customValidationMessages());

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }

        return true;
    }
}
