import { apiFetchJSON } from '@/utils/apiClient';

export interface EmailProvider {
  id?: string;
  name: string;
  smtpHost: string;
  smtpPort: number;
  tls: boolean;
  startTLS: boolean;
  authRequired: boolean;
  instructions: string;
  server?: string;
  port?: number;
  security?: 'none' | 'tls' | 'starttls';
}

export interface WebhookTemplate {
  id?: string;
  service: string;
  name: string;
  urlPattern: string;
  method: string;
  headers: Record<string, string>;
  payloadTemplate: string;
  instructions: string;
  description?: string;
  template?: {
    url?: string;
    method?: string;
    headers?: Record<string, string>;
    body?: string;
  };
}

export interface EmailConfig {
  enabled: boolean;
  provider: string;
  server: string;
  port: number;
  username: string;
  password?: string;
  from: string;
  to: string[];
  tls: boolean;
  startTLS: boolean;
}

export interface Webhook {
  id: string;
  name: string;
  url: string;
  method: string;
  headers: Record<string, string>;
  template?: string;
  enabled: boolean;
  service?: string; // Added to support Discord, Slack, etc.
  customFields?: Record<string, string>;
}

export interface AppriseConfig {
  enabled: boolean;
  mode?: 'cli' | 'http';
  targets?: string[];
  cliPath?: string;
  timeoutSeconds?: number;
  serverUrl?: string;
  configKey?: string;
  apiKey?: string;
  apiKeyHeader?: string;
  skipTlsVerify?: boolean;
}

export interface NotificationTestRequest {
  type: 'email' | 'webhook' | 'apprise';
  config?: Record<string, unknown>; // Backend expects different format than frontend types
  webhookId?: string;
}

export class NotificationsAPI {
  private static baseUrl = '/api/notifications';

  static async getAppriseConfig(): Promise<AppriseConfig> {
    return apiFetchJSON(`${this.baseUrl}/apprise`);
  }

  static async updateAppriseConfig(config: AppriseConfig): Promise<AppriseConfig> {
    return apiFetchJSON(`${this.baseUrl}/apprise`, {
      method: 'PUT',
      body: JSON.stringify(config),
    });
  }

  // Email configuration
  static async getEmailConfig(): Promise<EmailConfig> {
    const backendConfig = await apiFetchJSON<Record<string, unknown>>(`${this.baseUrl}/email`);

    // Backend already returns fields with correct names (server, port)
    return {
      enabled: (backendConfig.enabled as boolean) || false,
      provider: (backendConfig.provider as string) || '',
      server: (backendConfig.server as string) || '',
      port: (backendConfig.port as number) || 587,
      username: (backendConfig.username as string) || '',
      password: (backendConfig.password as string) || '',
      from: (backendConfig.from as string) || '',
      to: (backendConfig.to as string[]) || [],
      tls: (backendConfig.tls as boolean) || false,
      startTLS: (backendConfig.startTLS as boolean) || false,
    };
  }

  static async updateEmailConfig(config: EmailConfig): Promise<{ success: boolean }> {
    // Backend expects fields with these names (server, port)
    const backendConfig = {
      enabled: config.enabled,
      server: config.server,
      port: config.port,
      username: config.username,
      password: config.password,
      from: config.from,
      to: config.to,
      tls: config.tls || false,
      startTLS: config.startTLS || false,
      provider: config.provider || '',
    };

    return apiFetchJSON(`${this.baseUrl}/email`, {
      method: 'PUT',
      body: JSON.stringify(backendConfig),
    });
  }

  // Webhook management
  static async getWebhooks(): Promise<Webhook[]> {
    const data = await apiFetchJSON<Webhook[] | null>(`${this.baseUrl}/webhooks`);
    return Array.isArray(data) ? data : [];
  }

  static async createWebhook(webhook: Omit<Webhook, 'id'>): Promise<Webhook> {
    return apiFetchJSON(`${this.baseUrl}/webhooks`, {
      method: 'POST',
      body: JSON.stringify(webhook),
    });
  }

  static async updateWebhook(id: string, webhook: Partial<Webhook>): Promise<Webhook> {
    return apiFetchJSON(`${this.baseUrl}/webhooks/${id}`, {
      method: 'PUT',
      body: JSON.stringify(webhook),
    });
  }

  static async deleteWebhook(id: string): Promise<{ success: boolean }> {
    return apiFetchJSON(`${this.baseUrl}/webhooks/${id}`, {
      method: 'DELETE',
    });
  }

  // Templates and providers
  static async getEmailProviders(): Promise<EmailProvider[]> {
    return apiFetchJSON(`${this.baseUrl}/email-providers`);
  }

  static async getWebhookTemplates(): Promise<WebhookTemplate[]> {
    return apiFetchJSON(`${this.baseUrl}/webhook-templates`);
  }

  // Testing
  static async testNotification(
    request: NotificationTestRequest,
  ): Promise<{ success: boolean; message?: string }> {
    const body: { method: string; config?: Record<string, unknown>; webhookId?: string } = {
      method: request.type,
    };

    // Include config if provided for testing without saving
    if (request.config) {
      body.config = request.config;
    }

    // Include webhookId for webhook testing
    if (request.webhookId) {
      body.webhookId = request.webhookId;
    }

    return apiFetchJSON(`${this.baseUrl}/test`, {
      method: 'POST',
      body: JSON.stringify(body),
    });
  }

  static async testWebhook(
    webhook: Omit<Webhook, 'id'>,
  ): Promise<{ success: boolean; message?: string }> {
    return apiFetchJSON(`${this.baseUrl}/webhooks/test`, {
      method: 'POST',
      body: JSON.stringify(webhook),
    });
  }

  // Queue and DLQ management
  static async getQueueStats(): Promise<Record<string, number>> {
    return apiFetchJSON(`${this.baseUrl}/queue/stats`);
  }

  static async getDLQ(limit = 100): Promise<unknown[]> {
    return apiFetchJSON(`${this.baseUrl}/dlq?limit=${limit}`);
  }

  static async retryDLQItem(id: string): Promise<{ success: boolean }> {
    return apiFetchJSON(`${this.baseUrl}/dlq/retry`, {
      method: 'POST',
      body: JSON.stringify({ id }),
    });
  }

  static async deleteDLQItem(id: string): Promise<{ success: boolean }> {
    return apiFetchJSON(`${this.baseUrl}/dlq/delete`, {
      method: 'POST',
      body: JSON.stringify({ id }),
    });
  }

  static async getNotificationHealth(): Promise<{
    queue?: {
      healthy: boolean;
      pending: number;
      sending: number;
      sent: number;
      failed: number;
      dlq: number;
    };
    email: {
      enabled: boolean;
      configured: boolean;
    };
    webhooks: {
      total: number;
      enabled: number;
    };
    encryption: {
      enabled: boolean;
    };
    healthy: boolean;
  }> {
    return apiFetchJSON(`${this.baseUrl}/health`);
  }

  static async getWebhookHistory(): Promise<unknown[]> {
    return apiFetchJSON(`${this.baseUrl}/webhook-history`);
  }
}
