// sqs.service.ts
import {
    SQSClient,
    SendMessageCommand,
    ReceiveMessageCommand,
    DeleteMessageCommand,
    CreateQueueCommand,
    GetQueueUrlCommand,
} from '@aws-sdk/client-sqs';
import {Injectable, Logger, OnModuleInit} from '@nestjs/common';

export const SQS_QUEUES_NAME = {
    REALFLASHKAZE: 'q_realflashkaze',
    ECHCOMVUIVE: 'q_echcomvuive'
}

@Injectable()
export class SqsService implements OnModuleInit {
    private readonly logger = new Logger(SqsService.name);
    private client: SQSClient;

    private baseUrl = process.env.SQS_ENDPOINT + '000000000000';

    // // 👉 define tất cả queue ở đây
    // private queues = [
    //     'post-acc1',
    //     'post-acc2',
    // ];

    constructor() {
        this.client = new SQSClient({
            region: 'elasticmq',
            endpoint: process.env.SQS_ENDPOINT,
            credentials: {
                accessKeyId: 'x',
                secretAccessKey: 'x',
            },
        });
    }

    async onModuleInit() {
        this.logger.log('Initializing queues...');
        for (const name of Object.values(SQS_QUEUES_NAME)) {
            await this.ensureQueue(name);
        }
        this.logger.log('All queues ready ✅');
    }

    getQueueUrl(name: string) {
        return `${this.baseUrl}/${name}`;
    }

    private async ensureQueue(name: string) {
        try {
            await this.client.send(new CreateQueueCommand({
                QueueName: name,
            }));

            this.logger.log(`Queue ensured: ${name}`);
        } catch (err) {
            this.logger.error(`Failed to ensure queue ${name}`, err);
        }
    }

    // private async ensureQueue(name: string) {
    //     try {
    //         await this.client.send(new GetQueueUrlCommand({
    //             QueueName: name,
    //         }));
    //
    //         this.logger.log(`Queue exists: ${name}`);
    //     } catch (err) {
    //         this.logger.warn(`Queue missing → creating: ${name}`);
    //
    //         await this.client.send(new CreateQueueCommand({
    //             QueueName: name,
    //             Attributes: {
    //                 VisibilityTimeout: '60',
    //                 MessageRetentionPeriod: '86400', // 1 ngày
    //             },
    //         }));
    //
    //         this.logger.log(`Queue created: ${name}`);
    //     }
    // }

    // =====================
    // Core APIs
    // =====================

    async enqueue(name: string, data: any, opts?: {
        delaySeconds?: number;
        jobId?: string;
    }) {
        const queueUrl = this.getQueueUrl(name);

        // console.log(`QueueUrl: ${queueUrl}`);

        const body = {
            ...data,
            _jobId: opts?.jobId,
            _ts: Date.now(),
        };
        try {
            const data = await this.client.send(new SendMessageCommand({
                QueueUrl: queueUrl,
                MessageBody: JSON.stringify(body),
                DelaySeconds: opts?.delaySeconds || 0,
            }))
            console.log("Gửi thành công! MessageId:", data.MessageId);
        } catch (err) {
            console.error("Lỗi khi gửi tin nhắn:", err.message);
            throw err;
        }
        // return this.client.send(new SendMessageCommand({
        //     QueueUrl: queueUrl,
        //     MessageBody: JSON.stringify(body),
        //     DelaySeconds: opts?.delaySeconds || 0,
        // })).then(()=> {
        //     this.logger.log(`Queue enqueued: ${name}`);
        // });
    }

    async receive(name: string) {
        const queueUrl = this.getQueueUrl(name);

        const res = await this.client.send(new ReceiveMessageCommand({
            QueueUrl: queueUrl,
            MaxNumberOfMessages: 1,
            WaitTimeSeconds: 10,
            VisibilityTimeout: 60,
        }));

        if (!res.Messages?.length) return null;

        const msg = res.Messages[0];

        return {
            raw: msg,
            body: JSON.parse(msg.Body!),
        };
    }

    async ack(name: string, receiptHandle: string) {
        const queueUrl = this.getQueueUrl(name);

        await this.client.send(new DeleteMessageCommand({
            QueueUrl: queueUrl,
            ReceiptHandle: receiptHandle,
        }));
    }
}
