'use strict';
const ChannelBase = require('./channel-base');
const eventBus = require('../events/event-bus');

class SlackChannel extends ChannelBase {
  constructor(opts = {}) {
    super('slack_dm');
    this.botToken = opts.botToken || process.env.SLACK_BOT_TOKEN || null;
    this.pollInterval = opts.pollInterval || 5000; // 5s
    this.lastTimestamp = null;
    this._pollTimer = null;
    this._onMessage = opts.onMessage || null;
    this._botUserId = null;
  }

  async start() {
    if (!this.botToken) {
      console.log('[slack_dm] No bot token configured, skipping');
      return;
    }
    this.running = true;

    // Get bot user ID
    try {
      const res = await this._api('auth.test');
      this._botUserId = res.user_id;
      console.log(`[slack_dm] Listening as bot user ${this._botUserId}`);
    } catch (err) {
      console.error('[slack_dm] Auth failed:', err.message);
      this.running = false;
      return;
    }

    this._poll();
  }

  async stop() {
    this.running = false;
    if (this._pollTimer) clearTimeout(this._pollTimer);
  }

  _poll() {
    if (!this.running) return;
    this._checkMessages().catch(err => {
      console.error('[slack_dm] Poll error:', err.message);
    }).finally(() => {
      if (this.running) {
        this._pollTimer = setTimeout(() => this._poll(), this.pollInterval);
      }
    });
  }

  async _checkMessages() {
    // Get DM conversations
    const convRes = await this._api('conversations.list', { types: 'im', limit: 20 });
    if (!convRes.channels) return;

    for (const dm of convRes.channels) {
      const histRes = await this._api('conversations.history', {
        channel: dm.id,
        limit: 5,
        oldest: this.lastTimestamp || String(Date.now() / 1000 - 60),
      });

      if (!histRes.messages) continue;

      for (const msg of histRes.messages.reverse()) {
        // Skip bot's own messages and messages we've already seen
        if (msg.user === this._botUserId) continue;
        if (this.lastTimestamp && msg.ts <= this.lastTimestamp) continue;

        this.lastTimestamp = msg.ts;
        console.log(`[slack_dm] New DM from ${msg.user}: ${(msg.text || '').slice(0, 50)}...`);
        eventBus.emitMessage('slack_dm', msg.text, msg.user);

        if (this._onMessage && msg.text) {
          const response = await this._onMessage(msg.text, msg.user);
          if (response) await this.send(dm.id, response);
        }
      }
    }
  }

  async send(channelId, message) {
    try {
      await this._api('chat.postMessage', { channel: channelId, text: message });
      console.log(`[slack_dm] Sent reply to ${channelId}`);
    } catch (err) {
      console.error('[slack_dm] Send error:', err.message);
    }
  }

  async _api(method, params = {}) {
    const url = new URL(`https://slack.com/api/${method}`);
    const isGet = !['chat.postMessage'].includes(method);

    let res;
    if (isGet) {
      Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
      res = await fetch(url.toString(), {
        headers: { 'Authorization': `Bearer ${this.botToken}` },
      });
    } else {
      res = await fetch(url.toString(), {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${this.botToken}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(params),
      });
    }

    const data = await res.json();
    if (!data.ok) throw new Error(`Slack API error: ${data.error}`);
    return data;
  }
}

module.exports = SlackChannel;
