<?php

namespace App\Console\Commands\Migrations;

use App\Models\Association;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class AssociationLogoMigration extends BaseMigration
{
    protected string $oldTableName = 'sek_users';

    protected string $modelName = 'Association Logo';

    public function migrate(bool $dryRun = false, int $batchSize = 1000, int $startFrom = 0): void
    {
        $oldDb = DB::connection($this->connection);
        $this->processData($oldDb, $dryRun, $startFrom, $batchSize);
    }

    protected function getModelName(): string
    {
        return 'Association Logo';
    }

    protected function getModelClass(): string
    {
        return 'App\\Models\\Association';
    }

    protected function processData($oldDb, bool $dryRun, int $startFrom, int $batchSize): void
    {
        // Get users with association logos
        $query = $oldDb->table($this->oldTableName)
            ->whereNotNull('association_logo')
            ->whereNotNull('association_id')
            ->where('association_logo', '!=', '')
            ->where('association_id', '>', 0)
            ->orderBy('id')
            ->offset($startFrom);

        $totalRecords = $oldDb->table($this->oldTableName)
            ->whereNotNull('association_logo')
            ->whereNotNull('association_id')
            ->where('association_logo', '!=', '')
            ->where('association_id', '>', 0)
            ->count();

        $this->info("📊 Found {$totalRecords} association logos to migrate");

        if ($totalRecords === 0) {
            $this->info('✅ No association logos to migrate');

            return;
        }

        $bar = $this->command->getOutput()->createProgressBar($totalRecords);
        $bar->start();

        $query->chunk($batchSize, function ($oldRecords) use ($dryRun, $bar) {
            foreach ($oldRecords as $oldRecord) {
                $bar->advance();

                $data = $this->mapData($oldRecord);

                if ($this->validateData($data)) {
                    try {
                        if (! $dryRun) {
                            $this->createModel($data);
                        }
                        $this->stats['migrated']++;
                    } catch (\Exception $e) {
                        $this->stats['errors']++;
                        $this->error("❌ Error migrating logo for association {$data['association_id']}: {$e->getMessage()}");
                    }
                } else {
                    $this->stats['skipped']++;
                    $this->warn("⚠️  Skipped logo for association {$oldRecord->association_id} (validation failed)");
                }
            }
        });

        $bar->finish();
        $this->info('');
    }

    protected function mapData(object $oldRecord): array
    {
        // Add the /sekaya/ prefix to the logo path for MinIO storage
        $logoPath = $oldRecord->association_logo;
        if (! str_starts_with($logoPath, '/sekaya/')) {
            $logoPath = '/sekaya/'.ltrim($logoPath, '/'); // Add '/sekaya/' prefix
        }

        return [
            'association_id' => $oldRecord->association_id,
            'logo_path' => $logoPath,
            'original_path' => $oldRecord->association_logo,
        ];
    }

    protected function validateData(array $data): bool
    {
        // Check if association exists
        $association = Association::find($data['association_id']);
        if (! $association) {
            $this->warn("⚠️  Association {$data['association_id']} not found");

            return false;
        }

        // Check if association already has a logo
        if ($association->hasMedia('logo')) {
            $this->info("ℹ️  Association {$data['association_id']} already has a logo, skipping");

            return false;
        }

        // Check if file exists in storage
        if (! Storage::disk('s3')->exists($data['logo_path'])) {
            $this->warn("⚠️  Logo file not found in storage: {$data['logo_path']}");

            return false;
        }

        return true;
    }

    protected function createModel(array $data): void
    {
        $association = Association::find($data['association_id']);

        try {
            // Get file content from S3
            $fileContent = Storage::disk('s3')->get($data['logo_path']);
            $fileName = basename($data['logo_path']);

            // Determine mime type from file extension
            $extension = pathinfo($fileName, PATHINFO_EXTENSION);
            $mimeType = match (strtolower($extension)) {
                'jpg', 'jpeg' => 'image/jpeg',
                'png' => 'image/png',
                'gif' => 'image/gif',
                'svg' => 'image/svg+xml',
                default => 'image/jpeg' // Default fallback
            };

            if (! $fileContent) {
                throw new \Exception('Could not read file content from S3');
            }

            // Create a temporary local file
            $tempLocalPath = storage_path('app/tmp/logo_migration_'.uniqid().'_'.$fileName);

            // Ensure the tmp directory exists
            if (! file_exists(dirname($tempLocalPath))) {
                mkdir(dirname($tempLocalPath), 0755, true);
            }

            file_put_contents($tempLocalPath, $fileContent);

            // Add media to collection
            $media = $association->addMedia($tempLocalPath)
                ->usingName($fileName)
                ->usingFileName($fileName)
                ->withCustomProperties([
                    'original_path' => $data['original_path'],
                    'migrated_from_old_system' => true,
                    'migration_date' => now()->toISOString(),
                ])
                ->toMediaCollection('logo');

            // Clean up temporary file
            if (file_exists($tempLocalPath)) {
                unlink($tempLocalPath);
            }

            $this->info("📷 Migrated logo for association {$data['association_id']}: {$fileName}");

            // Log the successful migration
            Log::info('Association logo migrated', [
                'association_id' => $data['association_id'],
                'original_path' => $data['original_path'],
                'new_media_id' => $media->id,
                'file_name' => $fileName,
                'mime_type' => $mimeType,
            ]);
        } catch (\Exception $e) {
            // Clean up temporary file if it exists
            if (isset($tempLocalPath) && file_exists($tempLocalPath)) {
                unlink($tempLocalPath);
            }

            throw new \Exception("Failed to migrate logo: {$e->getMessage()}");
        }
    }
}
