import {
  ElementorElement,
  ElementorTemplate,
  ElementorDimension,
  ElementorWidgetSettings,
  ElementorContainerSettings,
  GenerationResult,
  WidgetType,
} from '../types/elementor';
import {
  AnalysisResult,
  AnalyzedSection,
  AnalyzedElement,
  GlobalStyles,
} from '../types/analysis';
import { getVersionDefinition, getLatestVersion, supportsContainers } from './versionRegistry';

let widgetCount = 0;

function uid(): string {
  return Math.random().toString(36).substring(2, 10);
}

function px(size: number | undefined, fallback = 0): { size: number; unit: 'px' } {
  return { size: size ?? fallback, unit: 'px' };
}

function dim(
  top = 0, right = 0, bottom = 0, left = 0,
  unit: 'px' | 'em' | '%' = 'px',
  linked = false
): ElementorDimension {
  return {
    top: String(top), right: String(right),
    bottom: String(bottom), left: String(left),
    unit, isLinked: linked,
  };
}

// ─── Widget builders ────────────────────────────────────────────────────────

function buildHeadingWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  const settings: ElementorWidgetSettings = {
    title: el.content ?? 'Heading',
    header_size: el.level ? (`h${el.level}` as ElementorWidgetSettings['header_size']) : 'h2',
    align: el.style.textAlign ?? 'left',
    title_color: el.style.color ?? undefined,
    typography_font_size: el.style.fontSize ? px(el.style.fontSize) : undefined,
    typography_font_weight: el.style.fontWeight ?? undefined,
    typography_font_family: el.style.fontFamily ?? undefined,
    _padding: el.style.paddingTop != null
      ? dim(el.style.paddingTop, el.style.paddingRight, el.style.paddingBottom, el.style.paddingLeft)
      : undefined,
  };

  return { id: uid(), elType: 'widget', widgetType: 'heading', settings, elements: [] };
}

function buildTextWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  const settings: ElementorWidgetSettings = {
    editor: `<p>${el.content ?? ''}</p>`,
    text_color: el.style.color ?? undefined,
    typography_font_size: el.style.fontSize ? px(el.style.fontSize) : undefined,
    typography_font_family: el.style.fontFamily ?? undefined,
    align: el.style.textAlign ?? 'left',
  };
  return { id: uid(), elType: 'widget', widgetType: 'text-editor', settings, elements: [] };
}

function buildButtonWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  const settings: ElementorWidgetSettings = {
    text: el.content ?? 'Click Here',
    link: el.href ? { url: el.href } : { url: '#' },
    align: el.style.textAlign ?? 'center',
    background_color: el.style.backgroundColor ?? undefined,
    button_text_color: el.style.color ?? undefined,
    size: 'md',
    border_radius: el.style.borderRadius != null
      ? dim(el.style.borderRadius, el.style.borderRadius, el.style.borderRadius, el.style.borderRadius)
      : dim(4, 4, 4, 4),
  };
  return { id: uid(), elType: 'widget', widgetType: 'button', settings, elements: [] };
}

function buildImageWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  const settings: ElementorWidgetSettings = {
    image: { url: el.src ?? '', alt: el.alt ?? '' },
    image_size: 'full',
    caption_source: 'none',
    align: el.style.textAlign ?? 'center',
  };
  return { id: uid(), elType: 'widget', widgetType: 'image', settings, elements: [] };
}

function buildDividerWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  const settings: ElementorWidgetSettings = {
    style: 'solid',
    color: el.style.color ?? '#E5E7EB',
    gap: px(20),
  };
  return { id: uid(), elType: 'widget', widgetType: 'divider', settings, elements: [] };
}

function buildSpacerWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  return {
    id: uid(), elType: 'widget', widgetType: 'spacer',
    settings: { space: px(el.style.paddingTop ?? 40) }, elements: [],
  };
}

function buildIconWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  return {
    id: uid(), elType: 'widget', widgetType: 'icon',
    settings: {
      icon: { value: 'fas fa-star', library: 'fa-solid' },
      icon_color: el.style.color ?? '#3B82F6',
      icon_size: px(el.style.fontSize ?? 40),
      align: el.style.textAlign ?? 'center',
    },
    elements: [],
  };
}

function buildListWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  return {
    id: uid(), elType: 'widget', widgetType: 'icon-list',
    settings: {
      icon_list: [
        { text: el.content ?? 'List item', icon: { value: 'fas fa-check', library: 'fa-solid' } },
      ],
    },
    elements: [],
  };
}

function buildTestimonialWidget(el: AnalyzedElement): ElementorElement {
  widgetCount++;
  return {
    id: uid(), elType: 'widget', widgetType: 'testimonial',
    settings: {
      testimonial_content: el.content ?? 'Testimonial text goes here.',
      testimonial_name: 'Customer Name',
      testimonial_job: 'Position, Company',
      testimonial_alignment: el.style.textAlign ?? 'center',
    },
    elements: [],
  };
}

function buildWidget(el: AnalyzedElement): ElementorElement | null {
  switch (el.type) {
    case 'heading':
    case 'subheading':
      return buildHeadingWidget({ ...el, level: el.type === 'subheading' ? (el.level ?? 3) : el.level });
    case 'paragraph':
      return buildTextWidget(el);
    case 'button':
      return buildButtonWidget(el);
    case 'image':
    case 'logo':
      return buildImageWidget(el);
    case 'divider':
      return buildDividerWidget(el);
    case 'spacer':
      return buildSpacerWidget(el);
    case 'icon':
      return buildIconWidget(el);
    case 'list':
      return buildListWidget(el);
    case 'testimonial':
      return buildTestimonialWidget(el);
    case 'nav':
      return buildTextWidget({ ...el, content: el.content ?? 'Navigation' });
    case 'form':
      // Forms require Pro and manual setup — generate placeholder
      return buildTextWidget({ ...el, content: '[Contact Form — configure in Elementor Pro]' });
    case 'video':
      return buildTextWidget({ ...el, content: '[Video widget — add URL in Elementor]' });
    case 'card':
      // Cards become inner containers handled separately
      return null;
    default:
      return buildTextWidget(el);
  }
}

// ─── Container builders ──────────────────────────────────────────────────────

function buildContainer(
  elements: ElementorElement[],
  settings: Partial<ElementorContainerSettings> = {}
): ElementorElement {
  return {
    id: uid(),
    elType: 'container',
    settings: {
      flex_direction: 'column',
      flex_justify_content: 'flex-start',
      flex_align_items: 'flex-start',
      content_width: 'boxed',
      ...settings,
    },
    elements,
    isInner: false,
  };
}

function buildRowContainer(children: ElementorElement[]): ElementorElement {
  return {
    id: uid(),
    elType: 'container',
    settings: {
      flex_direction: 'row',
      flex_justify_content: 'space-between',
      flex_align_items: 'flex-start',
      flex_wrap: 'wrap',
      content_width: 'full',
    } as ElementorContainerSettings,
    elements: children,
    isInner: true,
  };
}

// Build a column group (multi-column layout) using containers
function buildColumnGroup(el: AnalyzedElement): ElementorElement {
  const cols = el.columns ?? 3;
  const colContainers: ElementorElement[] = Array.from({ length: cols }, (_, i) => {
    const childEl = el.children?.[i];
    const childWidgets: ElementorElement[] = [];
    if (childEl) {
      const widget = buildWidget(childEl);
      if (widget) childWidgets.push(widget);
      if (childEl.children) {
        childEl.children.forEach((sub) => {
          const w = buildWidget(sub);
          if (w) childWidgets.push(w);
        });
      }
    }
    return {
      id: uid(),
      elType: 'container',
      settings: {
        flex_direction: 'column',
        content_width: 'full',
        flex_justify_content: 'flex-start',
        flex_align_items: 'flex-start',
      } as ElementorContainerSettings,
      elements: childWidgets,
      isInner: true,
    };
  });

  return buildRowContainer(colContainers);
}

// Build legacy section/column for pre-3.6
function buildLegacySection(
  elements: ElementorElement[],
  section: AnalyzedSection
): ElementorElement {
  const column: ElementorElement = {
    id: uid(),
    elType: 'column',
    settings: { _column_size: 100, content_position: 'top' },
    elements,
    isInner: false,
  };

  return {
    id: uid(),
    elType: 'section',
    settings: {
      layout: 'boxed',
      background_color: section.backgroundColor ?? undefined,
      padding: parseSectionPadding(section.padding),
    },
    elements: [column],
    isInner: false,
  };
}

function parseSectionPadding(padding?: string): ElementorDimension {
  // Rough parse of CSS shorthand like "60px 0" or "60px 20px"
  if (!padding) return dim(60, 0, 60, 0);
  const nums = padding.match(/\d+/g)?.map(Number) ?? [];
  if (nums.length === 1) return dim(nums[0], nums[0], nums[0], nums[0]);
  if (nums.length === 2) return dim(nums[0], nums[1], nums[0], nums[1]);
  if (nums.length === 4) return dim(nums[0], nums[1], nums[2], nums[3]);
  return dim(60, 0, 60, 0);
}

// ─── Section builder ─────────────────────────────────────────────────────────

function buildSection(
  section: AnalyzedSection,
  useContainers: boolean,
  globalStyles: GlobalStyles
): ElementorElement {
  const childWidgets: ElementorElement[] = [];

  for (const el of section.elements) {
    if (el.type === 'column-group' && useContainers) {
      childWidgets.push(buildColumnGroup(el));
    } else if (el.type === 'column-group' && !useContainers) {
      // Flatten columns for legacy layout
      if (el.children) {
        for (const child of el.children) {
          const w = buildWidget(child);
          if (w) childWidgets.push(w);
        }
      }
    } else if (el.type === 'card' && useContainers) {
      // Build card as inner container
      const cardChildren: ElementorElement[] = (el.children ?? [])
        .map(buildWidget)
        .filter(Boolean) as ElementorElement[];
      childWidgets.push(buildContainer(cardChildren, {
        background_color: el.style.backgroundColor ?? '#FFFFFF',
        border_border: 'solid' as const,
        border_width: dim(1, 1, 1, 1),
        border_color: '#E5E7EB',
        border_radius: dim(8, 8, 8, 8),
        padding: dim(
          el.style.paddingTop ?? 24,
          el.style.paddingRight ?? 24,
          el.style.paddingBottom ?? 24,
          el.style.paddingLeft ?? 24
        ),
      }));
    } else {
      const w = buildWidget(el);
      if (w) childWidgets.push(w);
    }
  }

  if (useContainers) {
    const containerSettings: Partial<ElementorContainerSettings> = {
      flex_direction: 'column',
      content_width: section.fullWidth ? 'full' : 'boxed',
      background_color: section.backgroundColor ?? undefined,
      padding: parseSectionPadding(section.padding),
      min_height: section.minHeight ? { size: 100, unit: 'vh' } : undefined,
    };

    if (section.backgroundImage) {
      containerSettings.background_background = 'image';
    }

    return buildContainer(childWidgets, containerSettings);
  }

  return buildLegacySection(childWidgets, section);
}

// ─── Main entry point ────────────────────────────────────────────────────────

export function buildElementorJSON(
  analysis: AnalysisResult,
  targetVersion: string
): GenerationResult {
  widgetCount = 0;

  const versionDef = getVersionDefinition(targetVersion) ?? getLatestVersion();
  const useContainers = versionDef.useContainers;
  const warnings = [...analysis.warnings];

  if (analysis.overallConfidence < 0.4) {
    warnings.push('Low analysis confidence — review all generated elements carefully.');
  }

  const content: ElementorElement[] = analysis.sections.map((section) =>
    buildSection(section, useContainers, analysis.globalStyles)
  );

  const template: ElementorTemplate = {
    version: versionDef.schemaVersion,
    title: 'Generated Page',
    type: 'page',
    page_settings: {
      background_color: analysis.globalStyles.backgroundColor,
      hide_title: 'yes',
      post_status: 'publish',
    },
    content,
  };

  return {
    template,
    targetVersion,
    warnings,
    confidence: analysis.overallConfidence,
    metadata: {
      sectionsCount: analysis.sections.length,
      widgetsCount: widgetCount,
      usesContainers: useContainers,
      generatedAt: new Date().toISOString(),
    },
  };
}
