import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { User } from '../../entities/user.entity';

export interface SlackBuildNotification {
  success: boolean;
  appName: string;
  platform: 'ios' | 'android';
  version: string;
  buildNumber: string;
  userName: string;
  userEmail: string;
  installUrl?: string;
  errorMessage?: string;
  releaseNotes?: string;
}

@Injectable()
export class SlackService {
  private readonly globalWebhookUrl: string | undefined;

  constructor(private configService: ConfigService) {
    this.globalWebhookUrl = this.configService.get<string>('SLACK_WEBHOOK_URL');
  }

  /**
   * Send a build notification to Slack
   * Uses user's personal webhook if configured, otherwise falls back to global webhook
   */
  async sendBuildNotification(
    notification: SlackBuildNotification,
    user?: User,
  ): Promise<void> {
    const webhookUrl = user?.slackWebhookUrl || this.globalWebhookUrl;

    if (!webhookUrl) {
      console.log('Slack notifications disabled (no webhook URL configured for user or globally)');
      return;
    }

    try {
      const payload = this.buildSlackMessage(notification);
      await this.sendToSlack(webhookUrl, payload);
    } catch (error) {
      console.error('Failed to send Slack notification:', error instanceof Error ? error.message : error);
    }
  }

  private buildSlackMessage(notification: SlackBuildNotification): any {
    const emoji = notification.success ? ':white_check_mark:' : ':x:';
    const color = notification.success ? '#36a64f' : '#ff0000';
    const status = notification.success ? 'Success' : 'Failed';
    const platformEmoji = notification.platform.toLowerCase() === 'ios' ? ':apple:' : ':robot_face:';

    const fields: any[] = [
      {
        title: 'App Name',
        value: notification.appName,
        short: true,
      },
      {
        title: 'Platform',
        value: `${platformEmoji} ${notification.platform.toUpperCase()}`,
        short: true,
      },
      {
        title: 'Version',
        value: notification.version,
        short: true,
      },
      {
        title: 'Build Number',
        value: notification.buildNumber,
        short: true,
      },
      {
        title: 'Uploaded By',
        value: `${notification.userName} (${notification.userEmail})`,
        short: false,
      },
    ];

    if (notification.success && notification.installUrl) {
      fields.push({
        title: 'Installation Link',
        value: `<${notification.installUrl}|Open Installation Page>`,
        short: false,
      });
    }

    if (!notification.success && notification.errorMessage) {
      fields.push({
        title: 'Error',
        value: notification.errorMessage,
        short: false,
      });
    }

    if (notification.releaseNotes) {
      fields.push({
        title: 'Release Notes',
        value: notification.releaseNotes.substring(0, 500), // Limit length
        short: false,
      });
    }

    return {
      text: `${emoji} Build ${status}: ${notification.appName} ${notification.version}`,
      attachments: [
        {
          color,
          title: `${emoji} Build ${status}`,
          fields,
          footer: 'DeployHub',
          ts: Math.floor(Date.now() / 1000),
        },
      ],
    };
  }

  private async sendToSlack(webhookUrl: string, payload: any): Promise<void> {
    const response = await fetch(webhookUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(payload),
    });

    if (!response.ok) {
      const text = await response.text();
      throw new Error(`Slack API error: ${response.status} ${text}`);
    }
  }

  /**
   * Send a test notification to verify Slack integration
   */
  async sendTestNotification(user?: User): Promise<boolean> {
    const webhookUrl = user?.slackWebhookUrl || this.globalWebhookUrl;

    if (!webhookUrl) {
      return false;
    }

    try {
      await this.sendToSlack(webhookUrl, {
        text: ':wave: DeployHub Slack integration is working!',
        attachments: [
          {
            color: '#36a64f',
            title: 'Test Notification',
            text: 'Your Slack webhook is configured correctly. You will receive build notifications in this channel.',
            footer: 'DeployHub',
            ts: Math.floor(Date.now() / 1000),
          },
        ],
      });
      return true;
    } catch (error) {
      console.error('Test notification failed:', error);
      return false;
    }
  }

  /**
   * Save Slack webhook URL for a user
   */
  async saveUserWebhook(
    user: User,
    webhookUrl: string,
    channelId?: string,
    workspaceId?: string,
  ): Promise<void> {
    user.slackWebhookUrl = webhookUrl;
    user.slackChannelId = channelId || null;
    user.slackWorkspaceId = workspaceId || null;
  }

  /**
   * Check if user has Slack configured
   */
  isUserSlackConfigured(user: User): boolean {
    return !!user.slackWebhookUrl || !!user.slackAccessToken;
  }

  /**
   * Check if Slack is enabled for user (checks both user and global settings)
   */
  async isSlackEnabledForUser(
    user: User,
    settingsRepo: any,
  ): Promise<boolean> {
    // Check user-specific override first
    if (user.slackEnabled !== null && user.slackEnabled !== undefined) {
      return user.slackEnabled;
    }

    // Fall back to global setting
    const settings = await settingsRepo.findOne({ where: { id: 'global' } });
    return settings?.slackEnabled ?? false;
  }

  /**
   * Disconnect Slack for a user
   */
  async disconnectUserSlack(user: User): Promise<void> {
    user.slackAccessToken = null;
    user.slackWebhookUrl = null;
    user.slackChannelId = null;
    user.slackWorkspaceId = null;
    user.slackBotUserId = null;
  }
}
