import { IDepositQueueStore, QueuedDepositEvent } from "./StateStoreContracts";
import { LaravelDepositClient } from "./LaravelDepositClient";

export class DepositWorkerService {
  constructor(
    private depositQueueService: IDepositQueueStore,
    private laravelDepositClient: LaravelDepositClient
  ) {}

  async processBatch(maxBatch: number = 100): Promise<{ processed: number; delivered: number; failed: number; remaining: number }> {
    const events = await this.depositQueueService.getProcessable(maxBatch);
    let delivered = 0;
    let failed = 0;

    for (const event of events) {
      await this.processOne(event)
        .then((result) => {
          if (result === "delivered") {
            delivered += 1;
          } else {
            failed += 1;
          }
        });
    }

    const stats = await this.depositQueueService.stats();
    // console.info("deposit worker batch complete", {
    //   processed: events.length,
    //   delivered,
    //   failed,
    //   remaining: stats.queued,
    // });

    return {
      processed: events.length,
      delivered,
      failed,
      remaining: stats.queued,
    };
  }

  private async processOne(event: QueuedDepositEvent): Promise<"delivered" | "failed"> {
    try {
      console.info("processing queued deposit", {
        tx_hash: event.tx_hash,
        payment_hash: event.payment_hash || null,
        user_id: event.user_id,
        attempt: event.attempts + 1,
      });
      await this.laravelDepositClient.persistDeposit(event);
      await this.depositQueueService.markDelivered(event);
      console.info("deposit delivered", { tx_hash: event.tx_hash, user_id: event.user_id });
      return "delivered";
    } catch (error: any) {
      const message = error?.message || "deposit delivery failed";
      await this.depositQueueService.markFailed(event, message);
      console.error("deposit delivery failed", {
        tx_hash: event.tx_hash,
        payment_hash: event.payment_hash || null,
        user_id: event.user_id,
        attempt: event.attempts + 1,
        error: message,
      });
      return "failed";
    }
  }
}
