<?php

namespace HelpGent\App\BackgroundServices;

defined( 'ABSPATH' ) || exit;

use Exception;
use HelpGent\App\BackgroundProcessors\BackgroundProcessor;
use HelpGent\App\EnumeratedList\AttachmentTransferQueueType;
use HelpGent\App\Models\Attachment as AttachmentModel;
use HelpGent\App\Models\AttachmentTransferQueue as AttachmentTransferQueueModel;
use HelpGent\App\DTO\AttachmentTransferQueueDTO;
use HelpGent\App\MediaDriverMigration\Migrator;

class MediaTransferService extends BackgroundService {
    public function boot(): void {
        $this->background_processor = new BackgroundProcessor( 'media_transfer' );

        $this->add_service_task( 'transfer_media' );
    }

    public static function transfer_media(): bool {
        $queue_type = AttachmentTransferQueueType::UPLOAD;

        // Attachment
        $attachment_data = AttachmentModel::query( 'attachment' )
            ->select(
                [
                    'attachment.*',
                    'queue.id as queue_id',
                    'queue.type',
                    'queue.transfer_from',
                    'queue.transfer_to',
                    'queue.transfer_next',
                    'queue.upload_id as queue_upload_id',
                    'queue.upload_token as queue_upload_token',
                    'queue.message',
                    'queue.status as queue_status',
                ]
            )
            ->left_join( AttachmentTransferQueueModel::get_table_name() . " as queue", 'queue.attachment_id', 'attachment.id' )
            ->where( 'queue.type', $queue_type )
            ->where_in( 'queue.status', [ 'transferring', 'in_queue' ] )
            ->order_by_raw( 'CASE WHEN queue.status = "transferring" THEN 1 WHEN queue.status = "in_queue" THEN 2 END ASC' )
            ->first();

        if ( empty( $attachment_data ) ) {
            return false;
        }

        /**
         * @var Migrator $migrator
         */
        $migrator = helpgent_singleton( Migrator::class );

        $attachment_transfer_queue = new AttachmentTransferQueueDTO();

        $attachment_transfer_queue->set_id( $attachment_data->queue_id )
            ->set_type( $attachment_data->type )
            ->set_attachment_id( $attachment_data->id )
            ->set_transfer_from( $attachment_data->transfer_from )
            ->set_transfer_to( $attachment_data->transfer_to )
            ->set_transfer_next( $attachment_data->transfer_next )
            ->set_upload_id( $attachment_data->queue_upload_id )
            ->set_upload_token( $attachment_data->queue_upload_token )
            ->set_status( $attachment_data->queue_status )
            ->set_message( $attachment_data->message );

        try {
            $migrator->transfer_from_queue( $attachment_transfer_queue );
        } catch ( Exception $e ) {
        }

        return true;
    }

    public function status(): string {
        return $this->background_process->status();
    }

    public function run(): void {
        parent::run();
        $this->set_expiration();
    }

    public function set_expiration(): void {
        $expiration = apply_filters( 'helpgent_media_transfer_processor_execution_expiration', MINUTE_IN_SECONDS * 30 );
        set_transient( 'helpgent_executed_media_transfer_processor', true, $expiration );
    }

    public function is_expired(): bool {
        return empty( get_transient( 'helpgent_executed_media_transfer_processor' ) );
    }
}