import { Request, Response, Router } from "express";
import { BlinkClientError } from "../providers/blink/BlinkClient";
import { BlinkInvoiceService } from "../providers/blink/BlinkInvoiceService";
import { BlinkWebhookProcessor } from "../providers/blink/BlinkWebhookProcessor";
import { WebhookRequestError } from "../services/AlchemyWebhookPayloadValidator";
import { DepositWorkerService } from "../services/DepositWorkerService";
import { IDepositQueueStore } from "../services/StateStoreContracts";

function toErrorMessage(error: unknown): string {
  return error instanceof Error ? error.message : String(error);
}

export function createBlinkRoutes(
  blinkInvoiceService: BlinkInvoiceService,
  blinkWebhookProcessor: BlinkWebhookProcessor,
  depositQueueService: IDepositQueueStore,
  depositWorkerService: DepositWorkerService
): Router {
  const router = Router();

  router.post("/lightning/blink/invoices", async (request: Request, response: Response) => {
    try {
      const payload = {
        user_id: Number(request.body?.user_id ?? request.body?.userId),
        amount_sats: Number(request.body?.amount_sats ?? request.body?.amountSats),
        currency: String(request.body?.currency || ""),
        reference: String(request.body?.reference || ""),
      };

      const invoice = await blinkInvoiceService.createInvoice(payload);
      return response.status(200).json(invoice);
    } catch (error: unknown) {
      if (error instanceof BlinkClientError) {
        console.error("blink invoice creation failed", {
          status: error.statusCode,
          message: error.message,
          details: error.details,
        });
        return response.status(error.statusCode).json({
          status: error.statusCode,
          error: "Unable to create Blink invoice",
        });
      }

      if (error instanceof WebhookRequestError) {
        return response.status(error.statusCode).json({
          status: error.statusCode,
          error: error.message,
        });
      }

      console.error("unexpected blink invoice route failure", {
        message: toErrorMessage(error),
      });

      return response.status(500).json({
        status: 500,
        error: "Unable to create Blink invoice",
      });
    }
  });

  router.post("/webhooks/blink", async (request: Request, response: Response) => {
    try {
      const { events, metrics } = await blinkWebhookProcessor.process(request.body);
      const queueResult = await depositQueueService.enqueue(events);

      void depositWorkerService.processBatch().catch((error: unknown) => {
        console.error("deposit worker batch failed", toErrorMessage(error));
      });

      return response.status(200).json({
        status: 200,
        data: {
          accepted: queueResult.accepted,
          duplicates: queueResult.duplicates,
          ignored: metrics.ignored,
          unsupported: metrics.unsupported,
          unmatched: metrics.unmatched,
        },
      });
    } catch (error: unknown) {
      if (error instanceof WebhookRequestError) {
        return response.status(error.statusCode).json({
          status: error.statusCode,
          error: error.message,
        });
      }

      console.error("unexpected blink webhook route failure", {
        message: toErrorMessage(error),
      });

      return response.status(500).json({
        status: 500,
        error: "Unable to process Blink webhook",
      });
    }
  });

  return router;
}
