/**
 * Integration Monitor Service
 *
 * Provides functionality for monitoring integration health,
 * tracking errors, and managing user integrations.
 */

import { integrationsAdapter } from '@/lib/adapters/integrations';

export type IntegrationType =
  | 'whatsapp'
  | 'google_calendar'
  | 'outlook_calendar'
  | 'salesforce'
  | 'hubspot'
  | 'zapier'
  | 'make';

export type IntegrationStatus = 'connected' | 'disconnected' | 'error' | 'pending_setup';

export interface IntegrationSummary {
  type: IntegrationType;
  displayName: string;
  totalUsers: number;
  connectedCount: number;
  errorCount: number;
  disconnectedCount: number;
  pendingCount: number;
  lastError: string | null;
  lastErrorAt: Date | null;
}

export interface IntegrationUser {
  id: string;
  userId: string;
  type: IntegrationType;
  status: IntegrationStatus;
  lastSyncAt: Date | null;
  lastError: string | null;
  createdAt: Date;
  updatedAt: Date;
  user: {
    id: string;
    email: string;
    name: string | null;
    companyName: string | null;
  };
}

export interface IntegrationHealthFilters {
  type?: IntegrationType;
  status?: IntegrationStatus;
  search?: string;
  page?: number;
  limit?: number;
}

const INTEGRATION_DISPLAY_NAMES: Record<IntegrationType, string> = {
  whatsapp: 'WhatsApp Business',
  google_calendar: 'Google Calendar',
  outlook_calendar: 'Microsoft Outlook',
  salesforce: 'Salesforce',
  hubspot: 'HubSpot',
  zapier: 'Zapier',
  make: 'Make (Integromat)',
};

/**
 * Get summary of all integration types
 */
export async function getIntegrationsSummary(): Promise<IntegrationSummary[]> {
  const integrationTypes: IntegrationType[] = [
    'whatsapp',
    'google_calendar',
    'outlook_calendar',
    'salesforce',
    'hubspot',
    'zapier',
    'make',
  ];

  const summaries: IntegrationSummary[] = [];

  for (const type of integrationTypes) {
    const [total, connected, errors, disconnected, pending, lastErrorEntry] = await Promise.all([
      integrationsAdapter.count({ where: { type } }),
      integrationsAdapter.count({ where: { type, status: 'connected' } }),
      integrationsAdapter.count({ where: { type, status: 'error' } }),
      integrationsAdapter.count({ where: { type, status: 'disconnected' } }),
      integrationsAdapter.count({ where: { type, status: 'pending_setup' } }),
      integrationsAdapter.findFirst({
        where: { type, status: 'error', lastError: { not: null } },
        orderBy: { updatedAt: 'desc' },
        select: { lastError: true, updatedAt: true },
      }),
    ]);

    summaries.push({
      type,
      displayName: INTEGRATION_DISPLAY_NAMES[type],
      totalUsers: total,
      connectedCount: connected,
      errorCount: errors,
      disconnectedCount: disconnected,
      pendingCount: pending,
      lastError: lastErrorEntry?.lastError || null,
      lastErrorAt: lastErrorEntry?.updatedAt || null,
    });
  }

  return summaries;
}

/**
 * Get users with a specific integration type
 */
export async function getIntegrationUsers(
  filters: IntegrationHealthFilters
): Promise<{
  users: IntegrationUser[];
  total: number;
  page: number;
  totalPages: number;
}> {
  const page = filters.page || 1;
  const limit = filters.limit || 25;
  const skip = (page - 1) * limit;

  const where: Record<string, unknown> = {};

  if (filters.type) {
    where.type = filters.type;
  }

  if (filters.status) {
    where.status = filters.status;
  }

  if (filters.search) {
    where.users = {
      OR: [
        { email: { contains: filters.search, mode: 'insensitive' } },
        { name: { contains: filters.search, mode: 'insensitive' } },
        { companyName: { contains: filters.search, mode: 'insensitive' } },
      ],
    };
  }

  const [integrations, total] = await Promise.all([
    integrationsAdapter.findMany({
      where,
      include: {
        users: {
          select: {
            id: true,
            email: true,
            name: true,
            companyName: true,
          },
        },
      },
      orderBy: [{ status: 'asc' }, { updatedAt: 'desc' }],
      skip,
      take: limit,
    }) as Promise<Array<Record<string, any>>>,
    integrationsAdapter.count({ where }),
  ]);

  return {
    users: integrations.map((integration: any) => ({
      id: integration.id,
      userId: integration.userId,
      type: integration.type as IntegrationType,
      status: integration.status as IntegrationStatus,
      lastSyncAt: integration.lastSyncAt,
      lastError: integration.lastError,
      createdAt: integration.createdAt,
      updatedAt: integration.updatedAt,
      user: {
        id: integration.users.id,
        email: integration.users.email,
        name: integration.users.name,
        companyName: integration.users.companyName,
      },
    })),
    total,
    page,
    totalPages: Math.ceil(total / limit),
  };
}

/**
 * Get integrations with errors
 */
export async function getIntegrationErrors(
  type?: IntegrationType
): Promise<{
  errors: Array<{
    id: string;
    type: IntegrationType;
    status: IntegrationStatus;
    lastError: string;
    lastSyncAt: Date | null;
    updatedAt: Date;
    user: {
      id: string;
      email: string;
      name: string | null;
    };
  }>;
}> {
  const where: Record<string, unknown> = {
    status: 'error',
    lastError: { not: null },
  };

  if (type) {
    where.type = type;
  }

  const integrations = await integrationsAdapter.findMany({
    where,
    include: {
      users: {
        select: {
          id: true,
          email: true,
          name: true,
        },
      },
    },
    orderBy: { updatedAt: 'desc' },
    take: 100,
  }) as Array<Record<string, any>>;

  return {
    errors: integrations.map((integration: any) => ({
      id: integration.id,
      type: integration.type as IntegrationType,
      status: integration.status as IntegrationStatus,
      lastError: integration.lastError!,
      lastSyncAt: integration.lastSyncAt,
      updatedAt: integration.updatedAt,
      user: {
        id: integration.users.id,
        email: integration.users.email,
        name: integration.users.name,
      },
    })),
  };
}

/**
 * Get integration health statistics
 */
export async function getIntegrationHealthStats(): Promise<{
  totalIntegrations: number;
  healthyCount: number;
  errorCount: number;
  disconnectedCount: number;
  healthPercentage: number;
  recentErrors: number;
}> {
  const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);

  const [total, healthy, errors, disconnected, recentErrors] = await Promise.all([
    integrationsAdapter.count(),
    integrationsAdapter.count({ where: { status: 'connected' } }),
    integrationsAdapter.count({ where: { status: 'error' } }),
    integrationsAdapter.count({ where: { status: 'disconnected' } }),
    integrationsAdapter.count({
      where: {
        status: 'error',
        updatedAt: { gte: yesterday },
      },
    }),
  ]);

  return {
    totalIntegrations: total,
    healthyCount: healthy,
    errorCount: errors,
    disconnectedCount: disconnected,
    healthPercentage: total > 0 ? Math.round((healthy / total) * 100) : 100,
    recentErrors,
  };
}

/**
 * Get display name for integration type
 */
export function getIntegrationDisplayName(type: IntegrationType): string {
  return INTEGRATION_DISPLAY_NAMES[type] || type;
}
