import { EmailBlock, CardBlock, ButtonBlock, ImageBlock, SpacerBlock, CardType, ButtonStyle, ContentWidth, ContentAlign } from './types';

/**
 * Convert HTML tags to markdown
 */
function convertHtmlToMarkdown(html: string): string {
  let markdown = html;

  // Headings
  markdown = markdown.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n\n');
  markdown = markdown.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n\n');
  markdown = markdown.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n\n');
  markdown = markdown.replace(/<h4[^>]*>(.*?)<\/h4>/gi, '#### $1\n\n');

  // Bold
  markdown = markdown.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**');
  markdown = markdown.replace(/<b[^>]*>(.*?)<\/b>/gi, '**$1**');

  // Italic
  markdown = markdown.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*');
  markdown = markdown.replace(/<i[^>]*>(.*?)<\/i>/gi, '*$1*');

  // Links
  markdown = markdown.replace(/<a[^>]*href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gi, '[$2]($1)');

  // Paragraphs
  markdown = markdown.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n');

  // Line breaks
  markdown = markdown.replace(/<br\s*\/?>/gi, '\n');

  // Lists
  markdown = markdown.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (match, content) => {
    return content.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n');
  });
  markdown = markdown.replace(/<ol[^>]*>([\s\S]*?)<\/ol>/gi, (match, content) => {
    let counter = 1;
    return content.replace(/<li[^>]*>(.*?)<\/li>/gi, () => `${counter++}. $1\n`);
  });

  // Clean up extra newlines
  markdown = markdown.replace(/\n{3,}/g, '\n\n');

  return markdown.trim();
}

/**
 * Convert blocks directly to clean markdown (no HTML pollution)
 */
export function blocksToMarkdown(blocks: EmailBlock[]): string {
  return blocks.map(block => {
    switch (block.type) {
      case 'card': {
        const cardBlock = block as CardBlock;
        // Use new [card:type] syntax
        const cardSyntax = cardBlock.cardType !== 'default' ? `[card:${cardBlock.cardType}]` : '[card]';
        return `${cardSyntax}\n\n${cardBlock.content}\n\n[/card]`;
      }

      case 'button': {
        const buttonBlock = block as ButtonBlock;
        // Use new [button:style](url)Text[/button] syntax
        const style = buttonBlock.style || 'solid';
        return `[button:${style}](${buttonBlock.link})${buttonBlock.text}[/button]`;
      }

      case 'image': {
        const imageBlock = block as ImageBlock;
        return `[image src="${imageBlock.src}" alt="${imageBlock.alt || ''}" width="${imageBlock.widthMode}" align="${imageBlock.align}"]`;
      }

      case 'divider':
        return '---';

      case 'spacer': {
        const spacerBlock = block as SpacerBlock;
        return `[spacer height="${spacerBlock.height}"]`;
      }

      default:
        return '';
    }
  }).join('\n\n');
}

/**
 * Convert blocks to [card] syntax HTML
 */
export function blocksToHTML(blocks: EmailBlock[]): string {
  return blocks.map(block => {
    switch (block.type) {
      case 'card':
        if (block.cardType === 'default') {
          return `[card]\n${block.content}\n[/card]`;
        }
        return `[card type="${block.cardType}"]\n${block.content}\n[/card]`;

      case 'button': {
        const buttonClass = block.style === 'solid' ? 'button' : 'button-outline';
        const align = block.align || 'center';
        let linkStyle = '';
        if (block.widthMode === 'full') {
          linkStyle = 'display:block;width:100%;text-align:center;';
        } else if (block.widthMode === 'custom' && block.customMaxWidth) {
          linkStyle = `display:block;max-width:${block.customMaxWidth}px;width:100%;margin:0 auto;`;
        }
        const styleAttr = linkStyle ? ` style="${linkStyle}"` : '';
        return `<p style="text-align: ${align};"><a href="${block.link}" class="${buttonClass}"${styleAttr}>${block.text}</a></p>`;
      }

      case 'image': {
        let wrapperStyle = `text-align: ${block.align};`;
        let imgStyle = '';
        if (block.widthMode === 'full') {
          imgStyle = 'display:block;width:100%;height:auto;';
        } else if (block.widthMode === 'custom' && block.customMaxWidth) {
          imgStyle = `display:block;max-width:${block.customMaxWidth}px;width:100%;height:auto;margin:0 auto;`;
        }
        return `<p style="${wrapperStyle}"><img src="${block.src}" alt="${block.alt || ''}" style="${imgStyle}" /></p>`;
      }

      case 'divider':
        return `<hr style="border: none; border-top: 1px solid #ddd; margin: 20px 0;" />`;

      case 'spacer':
        return `<div style="height: ${block.height}px;"></div>`;

      default:
        return '';
    }
  }).join('\n\n');
}

/**
 * Convert [card] syntax HTML or <div class="card"> HTML to blocks
 */
export function htmlToBlocks(html: string): EmailBlock[] {
  const blocks: EmailBlock[] = [];
  let blockId = 0;

  // Match both [card] syntax and <div class="card"> HTML
  const cardRegex = /(?:\[card([^\]]*)\]([\s\S]*?)\[\/card\]|<div class="card(?:\s+card-([^"]+))?"[^>]*>([\s\S]*?)<\/div>)/gs;
  const parts: string[] = [];
  let lastIndex = 0;
  let match;

  while ((match = cardRegex.exec(html)) !== null) {
    // Add content before card
    if (match.index > lastIndex) {
      const beforeContent = html.substring(lastIndex, match.index).trim();
      if (beforeContent) parts.push(beforeContent);
    }

    // Add card
    parts.push(match[0]);
    lastIndex = match.index + match[0].length;
  }

  // Add remaining content
  if (lastIndex < html.length) {
    const remaining = html.substring(lastIndex).trim();
    if (remaining) parts.push(remaining);
  }

  // Process each part
  for (const part of parts) {
    const id = `block-${Date.now()}-${blockId++}`;

    // Check if it's a card - match [card:type], [card type="..."], and <div class="card">
    let content = '';
    let cardType = 'default';

    // Try new [card:type] syntax first
    let cardMatch = part.match(/\[card:(\w+)\]([\s\S]*?)\[\/card\]/s);
    if (cardMatch) {
      cardType = cardMatch[1];
      content = cardMatch[2].trim();
    } else {
      // Try old [card type="..."] syntax
      cardMatch = part.match(/\[card([^\]]*)\]([\s\S]*?)\[\/card\]/s);
      if (cardMatch) {
        const attributes = cardMatch[1];
        content = cardMatch[2].trim();
        const typeMatch = attributes.match(/type=["']([^"']+)["']/);
        cardType = (typeMatch ? typeMatch[1] : 'default');
      }
    }

    if (!cardMatch) {
      // <div class="card"> HTML syntax
      const htmlCardMatch = part.match(/<div class="card(?:\s+card-([^"]+))?"[^>]*>([\s\S]*?)<\/div>/s);
      if (htmlCardMatch) {
        cardType = (htmlCardMatch[1] || 'default');
        content = htmlCardMatch[2].trim();
      }
    }

    if (content) {
      // Convert HTML content to markdown for clean editing
      // But only if it actually contains HTML tags
      const hasHtmlTags = /<[^>]+>/.test(content);
      const markdownContent = hasHtmlTags ? convertHtmlToMarkdown(content) : content;
      blocks.push({
        id,
        type: 'card',
        cardType: cardType as any,
        content: markdownContent
      });
      continue;
    }

    // Check if it's a button - try new syntax first
    let buttonMatch = part.match(/\[button:(\w+)\]\(([^)]+)\)([^\[]+)\[\/button\]/);
    if (buttonMatch) {
      const style = buttonMatch[1] as ButtonStyle;
      const url = buttonMatch[2];
      const text = buttonMatch[3].trim();

      blocks.push({
        id,
        type: 'button',
        link: url,
        text: text,
        style: style,
        align: 'center',
        widthMode: 'fit'
      });
      continue;
    }

    // Try old [button url="..."] syntax
    buttonMatch = part.match(/\[button\s+url=["']([^"']+)["'](?:\s+style=["'](\w+)["'])?\]([^\[]+)\[\/button\]/);
    if (buttonMatch) {
      const url = buttonMatch[1];
      const style = (buttonMatch[2] || 'solid') as ButtonStyle;
      const text = buttonMatch[3].trim();

      blocks.push({
        id,
        type: 'button',
        link: url,
        text: text,
        style: style,
        align: 'center',
        widthMode: 'fit'
      });
      continue;
    }

    // Check HTML button syntax
    if (part.includes('class="button"') || part.includes('class="button-outline"')) {
      const buttonMatch = part.match(/<a[^>]*href="([^"]*)"[^>]*class="(button[^"]*)"[^>]*style="([^"]*)"[^>]*>([^<]*)<\/a>/) ||
        part.match(/<a[^>]*href="([^"]*)"[^>]*class="(button[^"]*)"[^>]*>([^<]*)<\/a>/);
      if (buttonMatch) {
        const hasStyle = buttonMatch.length === 5;
        const styleAttr = hasStyle ? buttonMatch[3] : '';
        const textIndex = hasStyle ? 4 : 3;
        const styleClassIndex = 2;

        let widthMode: any = 'fit';
        let customMaxWidth: number | undefined = undefined;
        if (styleAttr.includes('width:100%') && !styleAttr.includes('max-width')) {
          widthMode = 'full';
        } else if (styleAttr.includes('max-width')) {
          widthMode = 'custom';
          const maxMatch = styleAttr.match(/max-width:(\d+)px/);
          if (maxMatch) {
            customMaxWidth = parseInt(maxMatch[1], 10);
          }
        }

        // Extract alignment from parent <p> tag if present
        const alignMatch = part.match(/text-align:\s*(left|center|right)/);
        const align = alignMatch ? alignMatch[1] as any : 'center';

        blocks.push({
          id,
          type: 'button',
          text: buttonMatch[textIndex],
          link: buttonMatch[1],
          style: buttonMatch[styleClassIndex].includes('outline') ? 'outline' : 'solid',
          widthMode,
          customMaxWidth,
          align,
        });
        continue;
      }
    }

    // Check if it's a divider
    if (part.includes('<hr')) {
      blocks.push({ id, type: 'divider' });
      continue;
    }

    // Check if it's a spacer
    const spacerMatch = part.match(/height:\s*(\d+)px/);
    if (spacerMatch && part.includes('<div')) {
      blocks.push({ id, type: 'spacer', height: parseInt(spacerMatch[1]) });
      continue;
    }
  }

  return blocks;
}

/**
 * Convert clean markdown directly to blocks (no HTML intermediary)
 */
export function markdownToBlocks(markdown: string): EmailBlock[] {
  const blocks: EmailBlock[] = [];
  let blockId = 0;

  // Parse markdown respecting [card]...[/card] and [button]...[/button] boundaries
  let remaining = markdown;

  while (remaining.length > 0) {
    remaining = remaining.trim();
    if (!remaining) break;

    const id = `block-${Date.now()}-${blockId++}`;

    // Check for [card] blocks - NEW syntax [card:type]...[/card]
    const newCardMatch = remaining.match(/^\[card:(\w+)\]([\s\S]*?)\[\/card\]/);
    if (newCardMatch) {
      const cardType = newCardMatch[1] as CardType;
      const content = newCardMatch[2].trim();

      blocks.push({
        id,
        type: 'card',
        cardType,
        content,
      });

      remaining = remaining.substring(newCardMatch[0].length);
      continue;
    }

    // Check for [card] blocks - OLD syntax [card type="..."]...[/card]
    const cardMatch = remaining.match(/^\[card([^\]]*)\]([\s\S]*?)\[\/card\]/);
    if (cardMatch) {
      const attributes = cardMatch[1].trim();
      const content = cardMatch[2].trim();

      // Extract card type
      const typeMatch = attributes.match(/type\s*=\s*["']([^"']+)["']/);
      const cardType = (typeMatch?.[1] || 'default') as CardType;

      // Extract background
      const bgMatch = attributes.match(/bg=["']([^"']+)["']/);
      const bg = bgMatch?.[1];

      blocks.push({
        id,
        type: 'card',
        cardType,
        content,
        bg,
      });

      // Advance past this card
      remaining = remaining.substring(cardMatch[0].length);
      continue;
    }

    // Check for [button] blocks - NEW syntax [button:style](url)Text[/button]
    const newButtonMatch = remaining.match(/^\[button:(\w+)\]\(([^)]+)\)([^\[]+)\[\/button\]/);
    if (newButtonMatch) {
      blocks.push({
        id,
        type: 'button',
        text: newButtonMatch[3].trim(),
        link: newButtonMatch[2],
        style: newButtonMatch[1] as ButtonStyle,
        align: 'center',
        widthMode: 'fit',
      });

      remaining = remaining.substring(newButtonMatch[0].length);
      continue;
    }

    // Check for [button] blocks - OLD syntax [button url="..." style="..."]Text[/button]
    const buttonMatch = remaining.match(/^\[button\s+url=["']([^"']+)["'](?:\s+style=["'](solid|outline)["'])?\]([^\[]+)\[\/button\]/);
    if (buttonMatch) {
      blocks.push({
        id,
        type: 'button',
        text: buttonMatch[3].trim(),
        link: buttonMatch[1],
        style: (buttonMatch[2] || 'solid') as ButtonStyle,
        align: 'center',
        widthMode: 'fit',
      });

      remaining = remaining.substring(buttonMatch[0].length);
      continue;
    }

    // Check for [image] blocks
    const imageMatch = remaining.match(/^\[image\s+src=["']([^"']+)["'](?:\s+alt=["']([^"']*)["'])?(?:\s+width=["']([^"']+)["'])?(?:\s+align=["']([^"']+)["'])?\]/);
    if (imageMatch) {
      blocks.push({
        id,
        type: 'image',
        src: imageMatch[1],
        alt: imageMatch[2] || '',
        widthMode: (imageMatch[3] || 'fit') as ContentWidth,
        align: (imageMatch[4] || 'center') as ContentAlign,
      });

      remaining = remaining.substring(imageMatch[0].length);
      continue;
    }

    // Check for [spacer] blocks
    const spacerMatch = remaining.match(/^\[spacer\s+height=["'](\d+)["']\]/);
    if (spacerMatch) {
      blocks.push({
        id,
        type: 'spacer',
        height: parseInt(spacerMatch[1]),
      });

      remaining = remaining.substring(spacerMatch[0].length);
      continue;
    }

    // Check for horizontal rule
    if (remaining.startsWith('---')) {
      blocks.push({
        id,
        type: 'divider',
      });

      remaining = remaining.substring(3);
      continue;
    }

    // If nothing matches, skip this character to avoid infinite loop
    remaining = remaining.substring(1);
  }

  return blocks;
}
