import { randomUUID } from 'node:crypto';

import { prisma } from '@hexahost/database';

import { logger } from '../logger';

function previousBillingPeriod(reference = new Date()): { start: Date; end: Date } {
  const start = new Date(
    Date.UTC(reference.getUTCFullYear(), reference.getUTCMonth() - 1, 1),
  );
  const end = new Date(Date.UTC(reference.getUTCFullYear(), reference.getUTCMonth(), 1));
  return { start, end };
}

export async function processWhmcsReconciliationTick(): Promise<void> {
  const now = new Date();
  if (now.getUTCHours() !== 3) {
    return;
  }

  const installations = await prisma.whmcsInstallation.findMany({
    where: { isActive: true },
    select: { id: true, integrationId: true },
  });

  for (const installation of installations) {
    try {
      await runInstallationReconciliation(installation.id, installation.integrationId);
    } catch (error) {
      logger.error(
        { err: error, installationId: installation.id },
        'WHMCS reconciliation tick failed',
      );
    }
  }
}

async function runInstallationReconciliation(
  installationId: string,
  integrationId: string,
): Promise<void> {
  const runId = randomUUID();
  const links = await prisma.whmcsServiceLink.findMany({
    where: { installationId },
    include: { server: { include: { plan: true } } },
  });

  const issues: Array<{
    code: string;
    severity: 'INFO' | 'WARNING' | 'BLOCKING' | 'DESTRUCTIVE' | 'SECURITY';
    message: string;
    externalServiceId?: string;
    serverId?: string;
  }> = [];

  for (const link of links) {
    if (link.status === 'SUSPENDED' && !link.server.billingSuspendedAt) {
      issues.push({
        code: 'status_mismatch_suspended',
        severity: 'BLOCKING',
        message: 'Suspended link without billing suspension',
        externalServiceId: link.externalServiceId,
        serverId: link.serverId,
      });
    }

    if (link.status === 'TERMINATED' && link.server.status !== 'DELETED') {
      issues.push({
        code: 'status_mismatch_terminated',
        severity: 'DESTRUCTIVE',
        message: 'Terminated link with active server',
        externalServiceId: link.externalServiceId,
        serverId: link.serverId,
      });
    }
  }

  if (issues.length === 0) {
    await prisma.whmcsServiceLink.updateMany({
      where: { installationId },
      data: { lastReconciledAt: new Date() },
    });
    return;
  }

  await prisma.reconciliationIssue.createMany({
    data: issues.map((issue) => ({
      installationId,
      runId,
      externalServiceId: issue.externalServiceId,
      serverId: issue.serverId,
      code: issue.code,
      severity: issue.severity,
      message: issue.message,
    })),
  });

  const blockingCount = issues.filter(
    (issue) => issue.severity === 'BLOCKING' || issue.severity === 'SECURITY',
  ).length;

  if (blockingCount > 0) {
    try {
      await prisma.integrationEvent.create({
        data: {
          installationId,
          eventType: 'reconciliation_required',
          payload: {
            runId,
            integrationId,
            issueCount: issues.length,
            blockingCount,
          },
          dedupeKey: `reconciliation:${installationId}:${runId}`,
        },
      });
    } catch {
      // duplicate dedupe
    }
  }

  await prisma.whmcsServiceLink.updateMany({
    where: { installationId },
    data: { lastReconciledAt: new Date() },
  });

  logger.info(
    { installationId, runId, issueCount: issues.length },
    'WHMCS reconciliation tick completed',
  );
}

export async function processWhmcsUsagePeriodTick(): Promise<void> {
  const now = new Date();
  if (now.getUTCDate() !== 1 || now.getUTCHours() > 1) {
    return;
  }

  const period = previousBillingPeriod(now);
  const installations = await prisma.whmcsInstallation.findMany({
    where: { isActive: true },
    select: { id: true },
  });

  for (const installation of installations) {
    const links = await prisma.whmcsServiceLink.findMany({
      where: {
        installationId: installation.id,
        status: { in: ['ACTIVE', 'SUSPENDED'] },
      },
      select: { externalServiceId: true, serverId: true },
    });

    for (const link of links) {
      const existing = await prisma.whmcsUsageExport.findUnique({
        where: {
          installationId_externalServiceId_periodStart_periodEnd_isTestMode: {
            installationId: installation.id,
            externalServiceId: link.externalServiceId,
            periodStart: period.start,
            periodEnd: period.end,
            isTestMode: false,
          },
        },
      });

      if (existing) {
        continue;
      }

      try {
        await prisma.integrationEvent.create({
          data: {
            installationId: installation.id,
            eventType: 'usage_period_ready',
            payload: {
              externalServiceId: link.externalServiceId,
              serverId: link.serverId,
              periodStart: period.start.toISOString(),
              periodEnd: period.end.toISOString(),
            },
            dedupeKey: `usage-ready:${installation.id}:${link.externalServiceId}:${period.start.toISOString()}`,
          },
        });
      } catch {
        // duplicate
      }
    }
  }
}
