<?php

namespace Mtc\Modules\BlockRegistry\Console\Commands;

use Illuminate\Console\Command;
use Mtc\Modules\BlockRegistry\Models\EntityBlock;
use Mtc\Modules\BlockRegistry\Services\ImageProcessingService;

class BlocksRegenerateImagesCommand extends Command
{
    protected $signature = 'blocks:regenerate-images {id? : Regenerate images for a specific entity block ID}';
    protected $description = 'Regenerate processed/cropped images for block registry image fields';

    public function handle(ImageProcessingService $imageProcessor): int
    {
        $id = $this->argument('id');

        $query = EntityBlock::with(['block', 'block.fields.subFields']);

        if ($id) {
            $query->where('id', $id);
        }

        if (!$query->exists()) {
            if ($id) {
                // A specific block was requested but doesn't exist — genuine failure
                $this->warn("Entity block #{$id} not found.");
                return self::FAILURE;
            }

            // Nothing to regenerate is a clean, successful no-op
            $this->info('No entity blocks found.');
            return self::SUCCESS;
        }

        $processed = 0;
        $images = 0;
        $errors = 0;

        $query->chunkById(100, function ($entityBlocks) use ($imageProcessor, &$processed, &$images, &$errors) {
            foreach ($entityBlocks as $entityBlock) {
                if (!$entityBlock->block || !$entityBlock->block->fields) {
                    continue;
                }

                $data = $entityBlock->data ?? [];
                $changed = false;

                foreach ($entityBlock->block->fields as $field) {
                    if ($field->type === 'image' && $imageProcessor->fieldHasCropEnabled($field)) {
                        try {
                            $result = $this->processImageField($imageProcessor, $entityBlock, $field, $data, $field->name);
                            if ($result !== null) {
                                $data[$field->name] = json_encode($result);
                                $changed = true;
                                $images++;
                            }
                        } catch (\Exception $e) {
                            $this->error("  Error processing {$field->name}: {$e->getMessage()}");
                            $errors++;
                        }
                    } elseif ($field->type === 'repeater' && $field->subFields) {
                        $rows = $this->parseRepeaterData($data[$field->name] ?? '[]');
                        if (!is_array($rows)) {
                            continue;
                        }

                        $rowChanged = false;
                        foreach ($field->subFields as $subField) {
                            if ($subField->type === 'image' && $imageProcessor->fieldHasCropEnabled($subField)) {
                                foreach ($rows as $rowIndex => &$row) {
                                    if (isset($row[$subField->name]) && is_array($row[$subField->name]) && !empty($row[$subField->name]['url'])) {
                                        try {
                                            $row[$subField->name] = $imageProcessor->processImageField(
                                                $entityBlock, $subField, $row[$subField->name], $rowIndex, $field->name
                                            );
                                            $rowChanged = true;
                                            $images++;
                                        } catch (\Exception $e) {
                                            $this->error("  Error processing {$subField->name} row {$rowIndex}: {$e->getMessage()}");
                                            $errors++;
                                        }
                                    }
                                }
                                unset($row);
                            }
                        }

                        if ($rowChanged) {
                            $data[$field->name] = json_encode(array_values($rows));
                            $changed = true;
                        }
                    }
                }

                if ($changed) {
                    $entityBlock->data = $data;
                    $entityBlock->save();
                    $processed++;
                    $this->info("Regenerated images for entity block #{$entityBlock->id} ({$entityBlock->block->name})");
                }
            }
        });

        $this->newLine();
        $this->info("Done. Blocks processed: {$processed}, Images regenerated: {$images}, Errors: {$errors}");

        return $errors > 0 ? self::FAILURE : self::SUCCESS;
    }

    protected function processImageField(
        ImageProcessingService $imageProcessor,
        EntityBlock $entityBlock,
        $field,
        array $data,
        string $fieldName
    ): ?array {
        $raw = $data[$fieldName] ?? null;
        if (empty($raw)) {
            return null;
        }

        $imageData = is_string($raw) ? json_decode($raw, true) : $raw;
        if (!is_array($imageData) || empty($imageData['url'])) {
            return null;
        }

        return $imageProcessor->processImageField($entityBlock, $field, $imageData);
    }

    protected function parseRepeaterData($value): ?array
    {
        if (is_array($value)) {
            return $value;
        }

        if (is_string($value)) {
            $decoded = json_decode($value, true);
            return is_array($decoded) ? $decoded : null;
        }

        return null;
    }
}
