<?php

namespace App\Extensions\Installed\Importer\Livewire\Database;

use Livewire\Component;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use App\Extensions\Installed\Importer\Models\ImportJob;
use App\Extensions\Installed\Importer\Services\DatabaseImporter;
use App\Extensions\Installed\Importer\Services\DatabaseAdapters\DatabaseAdapterRegistry;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

#[Layout('components.layouts.app', ['title' => 'Database Import Process', 'noPadding' => true])]
class Process extends Component
{
    public ImportJob $job;
    public $status = 'pending';
    public $progress = 0;
    public $stats = [
        'total' => 0,
        'processed' => 0,
        'failed' => 0,
    ];
    public $currentStage = null;
    public $stageTotals = [];
    public $eta = null;
    public $errors = [];
    public $dryRunResults = null;
    public $dryRunning = false;
    public $autoRefresh = true;
    public $sourceLabel = '';
    public $sourceSystem = 'supportpal';

    protected function resolveSourceLabel(string $system): string
    {
        try {
            return DatabaseAdapterRegistry::resolve($system)::label();
        } catch (\Throwable $e) {
            return Str::headline($system);
        }
    }

    public function mount(ImportJob $job)
    {
        $this->job = $job;
        $this->sourceSystem = $job->options['database_system'] ?? 'supportpal';
        $this->sourceLabel = $this->resolveSourceLabel($this->sourceSystem);
        $this->updateStats();
    }

    public function updateStats()
    {
        $this->job = $this->job->fresh();
        $this->sourceSystem = $this->job->options['database_system'] ?? 'supportpal';
        $this->sourceLabel = $this->resolveSourceLabel($this->sourceSystem);
        $this->status = $this->job->status;
        $this->progress = $this->job->getProgressPercentage();
        $this->stats = [
            'total' => $this->job->total_rows,
            'processed' => $this->job->processed_rows,
            'failed' => $this->job->failed_rows,
        ];
        $options = $this->job->options ?? [];
        $this->currentStage = Arr::get($options, 'state.current_stage');
        $this->stageTotals = Arr::get($options, 'totals', []);
        $this->eta = $this->job->etaForHumans();
        $this->errors = $this->job->errors ?? [];
        $this->dryRunResults = Arr::get($options, 'dry_run_results');
    }

    public function runDryRun()
    {
        $this->dryRunning = true;

        try {
            $importer = new DatabaseImporter($this->job->fresh());
            $results = $importer->simulate();

            $this->updateStats();
            $this->dryRunResults = $results;

            if (($results['issues'] ?? 0) > 0) {
                session()->flash('warning', sprintf(
                    'Dry run completed with %d potential issues. Review the details below before importing.',
                    $results['issues']
                ));
            } else {
                session()->flash('success', 'Dry run completed. No blocking issues detected — safe to import.');
            }
        } catch (\Throwable $e) {
            session()->flash('error', 'Dry run failed: ' . $e->getMessage());
        } finally {
            $this->dryRunning = false;
        }
    }

    public function startImport()
    {
        try {
            $freshJob = $this->job->fresh();
            $options = $freshJob->options ?? [];
            $options['dry_run'] = false;
            $freshJob->update(['options' => $options]);

            $importer = new DatabaseImporter($freshJob);
            $result = $importer->process(true);

            $this->updateStats();

            if (($result['status'] ?? null) === 'failed') {
                session()->flash('error', 'Import failed. Check the error log below for details.');
                return;
            }

            if ($this->status === 'processing' && $this->autoRefresh) {
                $this->dispatch('database-import-chunk-complete');
            }
        } catch (\Throwable $e) {
            session()->flash('error', 'Import chunk failed: ' . $e->getMessage());
            $this->updateStats();
        }
    }

    public function pauseImport()
    {
        $this->job->pause();
        $this->updateStats();
        session()->flash('message', 'Import paused. You can resume it later.');
    }

    public function resumeImport()
    {
        $this->job->resume();
        $this->updateStats();
        $this->startImport();
    }

    #[On('database-import-chunk-complete')]
    public function onChunkComplete()
    {
        if ($this->status === 'processing' && $this->autoRefresh) {
            $this->startImport();
        }
    }

    public function render()
    {
        return view('extension.importer::database.process');
    }
}
