<?php

namespace App\Console\Commands;

use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

#[Signature('migrate:entries:images {--wp-uploads-path=} {--limit=}')]
#[Description("Migrate WP Main images and galeries for entries.")]
class MigrateEntriesImages extends Command
{
    private const string GALLERYABLE_TYPE = 'App\\Models\\Entry';

    private function copyAttachment( int $attachmentId, string $wpUploadsPath, string $destinationPath ): ?string
    {
        $relativePath = DB::connection('old_wp')
            ->table('postmeta')
            ->where('post_id', $attachmentId)
            ->where('meta_key', '_wp_attached_file')
            ->value('meta_value');

        if( !$relativePath )
            return null;

        $sourcePath = rtrim($wpUploadsPath, '/') . '/' . $relativePath;
        if( !is_file($sourcePath) )
            return null;

        $extension = pathinfo($sourcePath, PATHINFO_EXTENSION);
        $filename = Str::random(40) . ($extension ? '.' . $extension : '');
        $destinationRelative = $destinationPath . '/' . $filename;

        $stream = fopen($sourcePath, 'r');
        Storage::disk('public')->put($destinationRelative, $stream);
        if( is_resource($stream) )
            fclose($stream);

        return $destinationRelative;
    }

    private function processEntry( int $wpPostId, int $entryId, string $wpUploadsPath, array &$stats ): void
    {
        $exists = DB::table('migrations_logs')
            ->where('source_system', 'wp')
            ->where('source_table', 'wp_posts__attachments')
            ->where('source_id', $wpPostId)
        ->exists();

        if( $exists )
            return;

        $thumbnailId = DB::connection('old_wp')
            ->table('postmeta')
            ->where('post_id', $wpPostId)
            ->where('meta_key', '_thumbnail_id')
            ->value('meta_value');

        if( $thumbnailId ){
            $newPath = $this->copyAttachment( (int) $thumbnailId, $wpUploadsPath, 'entries/main-images' );
            if( $newPath ){
                DB::table('entries')
                    ->where('id', $entryId)
                    ->update(['main_image' => $newPath]);
                $stats['main_image']++;
            } else {
                $stats['missing_files']++;
            }
        }

        $galleryRaw = DB::connection('old_wp')
            ->table('postmeta')
            ->where('post_id', $wpPostId)
            ->where('meta_key', 'my_gallery')
            ->value('meta_value');

        $attachmentIds = $galleryRaw ? (@unserialize($galleryRaw) ?: []) : [];

        foreach ( array_values( $attachmentIds ) as $order => $attachmentId ) {
            $newPath = $this->copyAttachment( (int) $attachmentId, $wpUploadsPath, "entries/gallery-images/{$entryId}" );
            if( !$newPath ){
                $stats['missing_files']++;
                continue;
            }

            DB::table('galleries')
                ->insert([
                    'galleryable_type' => self::GALLERYABLE_TYPE,
                    'galleryable_id' => $entryId,
                    'image' => $newPath,
                    'order' => $order,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            $stats['gallery_images']++;
        }

        DB::table('migrations_logs')
            ->insert([
                'source_system' => 'wp',
                'source_table' => 'wp_posts__attachments',
                'source_id' => $wpPostId,
                'target_table' => 'entries',
                'target_id' => $entryId,
                'status' => 'done',
                'migrated_at' => now(),
                'created_at' => now(),
                'updated_at' => now(),
            ]);
    }

    public function handle()
    {
        $wpUploadsPath = $this->option('wp-uploads-path');
        if( !$wpUploadsPath || !is_dir($wpUploadsPath) ){
            $this->error('Missing WP Uploads Path');
            return self::FAILURE;
        }

        $query = DB::table('migrations_logs')
            ->where('source_system', 'wp')
            ->where('source_table', 'wp_posts')
            ->where('target_table', 'entries')
        ;

        if( $limit = $this->option('limit') ){
            $query->limit((int)$limit);
        }

        $rows = $query->get(['source_id', 'target_id']);
        $this->info("{$rows->count()} entries need to be migrated");

        $stats = ['main_image' => 0, 'gallery_images' => 0, 'missing_files' => 0 ];

        $this->withProgressBar($rows, function($row) use($wpUploadsPath, &$stats) {
            $this->processEntry( $row->source_id, $row->target_id, $wpUploadsPath, $stats );
        });

        $this->newLine();
        $this->info("Migrated attachments. Main images: {$stats['main_image']}, Galleries: {$stats['gallery_images']}, Missing files: {$stats['missing_files']}");
        return self::SUCCESS;
    }
}
