import { CommandExecutionError } from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
    site: 'twitter',
    name: 'reply-dm',
    access: 'write',
    description: 'Send a message to recent DM conversations',
    domain: 'x.com',
    strategy: Strategy.UI,
    browser: true,
    args: [
        { name: 'text', type: 'string', required: true, positional: true, help: 'Message text to send (e.g. "我的微信 wxkabi")' },
        { name: 'max', type: 'int', required: false, default: 20, help: 'Maximum number of conversations to reply to (default: 20)' },
        { name: 'skip-replied', type: 'boolean', required: false, default: true, help: 'Skip conversations where you already sent the same text (default: true)' },
        { name: 'timeout', type: 'int', required: false, default: 600, help: 'Max seconds for the overall command (default: 600 — batch op)' },
    ],
    columns: ['index', 'status', 'user', 'message'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for twitter reply-dm');
        const messageText = kwargs.text;
        const maxSend = kwargs.max ?? 20;
        const skipReplied = kwargs['skip-replied'] !== false;
        const results = [];
        let sentCount = 0;
        // Step 1: Navigate to messages to get conversation list
        await page.goto('https://x.com/messages');
        await page.wait({ selector: '[data-testid="primaryColumn"]' });
        // Step 2: Collect conversations with scroll-to-load
        const needed = maxSend + 10; // extra buffer for skips
        const convList = await page.evaluate(`(async () => {
      try {
        // Wait for initial items
        let attempts = 0;
        while (attempts < 10) {
          const items = document.querySelectorAll('[data-testid^="dm-conversation-item-"], [data-testid="conversation"]');
          if (items.length > 0) break;
          await new Promise(r => setTimeout(r, 1000));
          attempts++;
        }

        // Scroll to load more conversations
        const needed = ${needed};
        const seenIds = new Set();
        let noNewCount = 0;

        for (let scroll = 0; scroll < 30; scroll++) {
          const items = Array.from(document.querySelectorAll('[data-testid^="dm-conversation-item-"], [data-testid="conversation"]'));
          items.forEach(el => seenIds.add(el.getAttribute('data-testid')));

          if (seenIds.size >= needed) break;

          // Find the scrollable container and scroll it
          const scrollContainer = document.querySelector('[data-testid="dm-inbox-panel"]') ||
                                  items[items.length - 1]?.closest('[class*="scroll"]') ||
                                  items[items.length - 1]?.parentElement;
          if (scrollContainer) {
            scrollContainer.scrollTop = scrollContainer.scrollHeight;
          }
          // Also try scrolling the last item into view
          if (items.length > 0) {
            items[items.length - 1].scrollIntoView({ behavior: 'instant', block: 'end' });
          }

          await new Promise(r => setTimeout(r, 1500));

          // Check if new items appeared
          const newItems = Array.from(document.querySelectorAll('[data-testid^="dm-conversation-item-"], [data-testid="conversation"]'));
          const newIds = new Set(newItems.map(el => el.getAttribute('data-testid')));
          if (newIds.size <= seenIds.size) {
            noNewCount++;
            if (noNewCount >= 3) break; // No more loading after 3 tries
          } else {
            noNewCount = 0;
          }
        }

        // Collect all visible conversations
        const finalItems = Array.from(document.querySelectorAll('[data-testid^="dm-conversation-item-"], [data-testid="conversation"]'));
        const conversations = finalItems.map((item, idx) => {
          const testId = item.getAttribute('data-testid') || '';
          const text = item.innerText || '';
          const lines = text.split('\\n').filter(l => l.trim());
          const user = lines[0] || 'Unknown';
          const match = testId.match(/dm-conversation-item-(.+)/);
          const convId = match ? match[1].replace(':', '-') : '';
          const link = item.querySelector('a[href*="/messages/"]');
          const href = link ? link.href : '';
          return { idx, user, convId, href, preview: text.substring(0, 100) };
        });

        return { ok: true, conversations, total: conversations.length };
      } catch(e) {
        return { ok: false, error: String(e), conversations: [], total: 0 };
      }
    })()`);
        if (!convList?.ok || !convList.conversations?.length) {
            return [{ index: 1, status: 'info', user: 'System', message: 'No conversations found' }];
        }
        const conversations = convList.conversations;
        // Step 3: Iterate through conversations and send message
        for (const conv of conversations) {
            if (sentCount >= maxSend)
                break;
            const convUrl = conv.convId
                ? `https://x.com/messages/${conv.convId}`
                : conv.href;
            if (!convUrl)
                continue;
            await page.goto(convUrl);
            await page.wait(3);
            const sendResult = await page.evaluate(`(async () => {
        try {
          const messageText = ${JSON.stringify(messageText)};
          const skipReplied = ${skipReplied};

          // Get username from conversation
          const dmHeader = document.querySelector('[data-testid="DmActivityContainer"] [dir="ltr"] span') ||
                           document.querySelector('[data-testid="conversation-header"]') ||
                           document.querySelector('[data-testid="DmActivityContainer"] h2');
          const username = dmHeader ? dmHeader.innerText.trim().split('\\\\n')[0] : '${conv.user}';

          // Check if we already sent this message
          if (skipReplied) {
            const chatArea = document.querySelector('[data-testid="DmScrollerContainer"]') ||
                             document.querySelector('main');
            const chatText = chatArea ? chatArea.innerText : '';
            if (chatText.includes(messageText)) {
              return { status: 'skipped', user: username, message: 'Already sent this message' };
            }
          }

          // Find the text input
          const input = document.querySelector('[data-testid="dmComposerTextInput"]');
          if (!input) {
            return { status: 'error', user: username, message: 'No message input found' };
          }

          // Focus and type into the DraftEditor
          input.focus();
          await new Promise(r => setTimeout(r, 300));
          document.execCommand('insertText', false, messageText);
          await new Promise(r => setTimeout(r, 500));

          // Click send button
          const sendBtn = document.querySelector('[data-testid="dmComposerSendButton"]');
          if (!sendBtn) {
            return { status: 'error', user: username, message: 'No send button found' };
          }

          sendBtn.click();
          await new Promise(r => setTimeout(r, 1500));

          return { status: 'sent', user: username, message: 'Message sent: ' + messageText };
        } catch(e) {
          return { status: 'error', user: 'system', message: String(e) };
        }
      })()`);
            if (sendResult?.status === 'sent') {
                sentCount++;
                results.push({
                    index: sentCount,
                    status: 'sent',
                    user: sendResult.user || conv.user,
                    message: sendResult.message,
                });
            }
            else if (sendResult?.status === 'skipped') {
                results.push({
                    index: results.length + 1,
                    status: 'skipped',
                    user: sendResult.user || conv.user,
                    message: sendResult.message,
                });
            }
            await page.wait(1);
        }
        if (results.length === 0) {
            results.push({ index: 0, status: 'info', user: 'System', message: 'No conversations processed' });
        }
        return results;
    }
});
