import Anthropic from '@anthropic-ai/sdk';
import { VersionDefinition } from './versionRegistry';
import { GenerationResult, ElementorTemplate } from '../types/elementor';

const client = new Anthropic();

function buildPrompt(versionDef: VersionDefinition): string {
  const widgetList = [
    'heading', 'text-editor', 'button', 'image', 'divider', 'spacer',
    'icon', 'icon-list', 'icon-box', 'nav-menu', 'social-icons', 'menu-anchor',
    'testimonial', 'testimonial-carousel', 'form', 'counter', 'accordion', 'tabs', 'video',
    ...(versionDef.features.loopGrid ? ['loop-grid'] : []),
    ...(versionDef.features.offCanvas ? ['off-canvas'] : []),
  ].join(', ');

  return `You are an expert Elementor Pro ${versionDef.version} developer.
Analyze this webpage screenshot and generate a complete, valid Elementor Pro JSON template that faithfully recreates the design.

OUTPUT: A single raw JSON object only. No markdown, no code fences, no explanation. Start with { and end with }.

━━━ ROOT STRUCTURE ━━━
{
  "version": "0.4",
  "title": "Page Title",
  "type": "page",
  "page_settings": [],
  "content": [ ...top-level containers... ]
}

━━━ CORE RULES ━━━
• All layout blocks → elType:"container"  |  All UI elements → elType:"widget"
• Top-level containers: "isInner":false   |  Containers nested inside another container: "isInner":true
• Widgets always have: elType:"widget", elements:[], isInner:false
• IDs: random 7–8 char lowercase hex (e.g. "3a7f1c2d")
• Available widgets: ${widgetList}

━━━ CONTAINER SETTINGS ━━━
{
  "flex_direction": "row" | "column",
  "flex_gap": {"unit":"px","size":0,"column":"0","row":"0"},
  "padding": {"unit":"px","top":"60","right":"0","bottom":"60","left":"0","isLinked":false},
  "content_width": "boxed" | "full",
  "boxed_width": {"unit":"px","size":1200,"sizes":[]},
  "width": {"unit":"%","size":33},
  "min_height": {"unit":"vh","size":80,"sizes":[]},
  "flex_justify_content": "flex-start"|"center"|"flex-end"|"space-between"|"space-evenly",
  "flex_align_items": "flex-start"|"center"|"flex-end"|"stretch",
  "background_background": "classic",
  "background_color": "#FFFFFF",
  "background_image": {"url":"https://...","id":0,"size":"","alt":"","source":"library"},
  "background_position": "center center",
  "background_size": "cover",
  "background_repeat": "no-repeat",
  "border_border": "solid",
  "border_width": {"unit":"px","top":"1","right":"0","bottom":"1","left":"0","isLinked":false},
  "border_color": "#E5E7EB",
  "sticky": "top",
  "hide_mobile": "hidden-mobile",
  "hide_desktop": "hidden-desktop",
  "hide_tablet": "hidden-tablet",
  "_title": "Internal Label"
}

GRID CONTAINER — for multi-column feature/icon grids:
add "container_type":"grid" plus:
  "grid_columns_grid": {"unit":"fr","size":3,"sizes":[]},
  "grid_rows_grid": {"unit":"fr","size":1,"sizes":[]},
  "grid_align_items": "center" | "start" | "end"

━━━ GLOBAL COLORS (__globals__) ━━━
Use __globals__ for theme colors instead of hardcoding hex:
  "globals/colors?id=primary"   — main brand color
  "globals/colors?id=secondary" — secondary color
  "globals/colors?id=accent"    — accent/CTA color
  "globals/colors?id=text"      — body text color
Example: "__globals__": {"title_color":"globals/colors?id=primary"}
Only hardcode hex when the color is clearly unique to that element.

━━━ TYPOGRAPHY PATTERN ━━━
Always include "typography_typography":"custom" first, then:
  "typography_font_size": {"unit":"px","size":24,"sizes":[]},
  "typography_font_weight": "700",
  "typography_font_family": "FontName"
For widget-prefix typography (icon-box, nav-menu etc.) use the prefix:
  "title_typography_typography":"custom", "title_typography_font_size":{...}
  "menu_typography_typography":"custom", "menu_typography_font_size":{...}

━━━ WIDGET EXAMPLES ━━━

heading:
{"id":"a1b2c3d4","elType":"widget","widgetType":"heading","isInner":false,"elements":[],"settings":{
  "title":"Your Heading","header_size":"h1","align":"center",
  "typography_typography":"custom","typography_font_size":{"unit":"px","size":48,"sizes":[]},"typography_font_weight":"700",
  "__globals__":{"title_color":"globals/colors?id=primary"},
  "typography_font_size_mobile":{"unit":"px","size":28,"sizes":[]}
}}

text-editor:
{"settings":{"editor":"<p>Paragraph text here.</p>","align":"center",
  "typography_typography":"custom","typography_font_size":{"unit":"px","size":18,"sizes":[]},"typography_font_weight":"400"}}

button:
{"settings":{
  "text":"Get Started",
  "link":{"url":"#","is_external":"","nofollow":"","custom_attributes":""},
  "align":"center","align_mobile":"justify",
  "typography_typography":"custom","typography_font_size":{"unit":"px","size":16,"sizes":[]},
  "__globals__":{"background_color":"globals/colors?id=accent"},
  "selected_icon":{"value":"fas fa-arrow-right","library":"fa-solid"},"icon_align":"right",
  "icon_indent":{"unit":"px","size":10,"sizes":[]}
}}

image:
{"settings":{
  "image":{"url":"https://via.placeholder.com/400x300","id":0,"size":"","alt":"","source":"library"},
  "image_size":"full","width":{"unit":"px","size":300,"sizes":[]},
  "link_to":"none"
}}

nav-menu:
{"settings":{
  "menu_name":"Main Menu","menu":"main-menu",
  "menu_typography_typography":"custom","menu_typography_font_size":{"unit":"px","size":16,"sizes":[]},"menu_typography_font_weight":"600",
  "pointer_width":{"unit":"px","size":0,"sizes":[]},
  "__globals__":{"color_menu_item":"globals/colors?id=secondary","color_menu_item_hover":"globals/colors?id=accent","color_menu_item_active":"globals/colors?id=accent","toggle_color":"globals/colors?id=accent"},
  "align_items":"center","full_width":"stretch",
  "toggle_background_color":"#02010100","toggle_size_mobile":{"unit":"px","size":27,"sizes":[]}
}}

icon-box:
{"settings":{
  "selected_icon":{"value":"fas fa-check-circle","library":"fa-solid"},
  "title_text":"Feature Title","description_text":"Feature description.",
  "text_align":"center",
  "icon_size":{"unit":"px","size":60,"sizes":[]},"icon_space":{"unit":"px","size":10,"sizes":[]},"title_bottom_space":{"unit":"px","size":5,"sizes":[]},
  "title_typography_typography":"custom","title_typography_font_size":{"unit":"px","size":18,"sizes":[]},"title_typography_font_weight":"700",
  "description_typography_typography":"custom","description_typography_font_size":{"unit":"px","size":14,"sizes":[]},
  "__globals__":{"primary_color":"globals/colors?id=accent"}
}}

icon-list:
{"settings":{
  "icon_list":[{"text":"List item","selected_icon":{"value":"fas fa-check","library":"fa-solid"},"_id":"a1b2c3","link":{"url":"","is_external":"","nofollow":"","custom_attributes":""}}],
  "view":"traditional","icon_size":{"unit":"px","size":18,"sizes":[]},
  "icon_typography_typography":"custom","icon_typography_font_size":{"unit":"px","size":16,"sizes":[]}
}}

social-icons:
{"settings":{
  "social_icon_list":[
    {"social_icon":{"value":"fab fa-facebook","library":"fa-brands"},"_id":"a1b2c3"},
    {"social_icon":{"value":"fab fa-instagram","library":"fa-brands"},"_id":"d4e5f6"}
  ],
  "shape":"circle","icon_size":{"unit":"px","size":20,"sizes":[]},
  "__globals__":{"icon_primary_color":"globals/colors?id=primary"}
}}

form:
{"settings":{
  "form_name":"Contact Form",
  "form_fields":[
    {"custom_id":"name","field_label":"Name","placeholder":"Your Name","width":"50","_id":"a1b2c3"},
    {"custom_id":"email","field_type":"email","field_label":"Email","placeholder":"Email","required":"true","width":"50","_id":"d4e5f6"},
    {"custom_id":"message","field_type":"textarea","field_label":"Message","placeholder":"Message","width":"100","_id":"g7h8i9"}
  ],
  "show_labels":"yes","button_width":"25","button_text":"Send",
  "email_content":"[all-fields]","email_content_2":"[all-fields]",
  "success_message":"Form sent successfully.","error_message":"Sending failed, please try again.",
  "__globals__":{"button_background_color":"globals/colors?id=accent"}
}}

testimonial-carousel:
{"settings":{
  "slides":[{"content":"Great experience!","name":"Customer Name","title":"","image":{"url":"","id":""},"_id":"a1b2c3"}],
  "skin":"bubble","slides_per_view":"3","slides_to_scroll":"1",
  "content_typography_typography":"custom","content_typography_font_size":{"unit":"px","size":14,"sizes":[]},"content_typography_font_weight":"400"
}}

spacer:
{"settings":{"space":{"unit":"px","size":40,"sizes":[]}}}

menu-anchor:
{"settings":{"anchor":"section-id"}}

divider:
{"settings":{"style":"solid","color":"#E5E7EB","gap":{"unit":"px","size":15,"sizes":[]}}}

counter:
{"settings":{
  "starting_number":0,"ending_number":100,"suffix":"+",
  "title":"Projects Completed",
  "number_typography_typography":"custom","number_typography_font_size":{"unit":"px","size":48,"sizes":[]},"number_typography_font_weight":"700",
  "__globals__":{"color":"globals/colors?id=accent"}
}}

━━━ RESPONSIVE RULES ━━━
• Desktop-only row (e.g. top bar): add "hide_mobile":"hidden-mobile","hide_tablet":"hidden-tablet" to the container
• Mobile-only alternative: "hide_desktop":"hidden-desktop","hide_tablet":"hidden-tablet"
• Mobile font overrides: "typography_font_size_mobile":{"unit":"px","size":22,"sizes":[]}
• Mobile layout: "flex_direction_mobile":"column","flex_justify_content_mobile":"center"
• Mobile min-height: "min_height_mobile":{"unit":"vh","size":50,"sizes":[]}

━━━ CRITICAL RULES ━━━
1. Generate ALL visible sections — don't skip any part of the design
2. For image placeholders use the exact URL pattern: "https://via.placeholder.com/WxH"
3. Multi-column layouts: outer container flex_direction:row → inner containers each with width:{unit:"%",size:N}
4. For icon/feature grids: use container_type:"grid" with grid_columns_grid
5. isInner:true on ALL containers that are children of another container
6. Never put widgetType on a container; never put elType:"widget" on layout blocks
7. typography_typography must always be "custom" when setting custom fonts/sizes
8. Include both desktop and mobile versions of hero/header sections when needed (use hide_* flags)
9. Estimate layout widths realistically from the screenshot (20%/60%/20% for 3-col header, etc.)
10. For the contact/lead form: use widgetType:"form" — it is available in Elementor Pro ${versionDef.version}

Analyze the screenshot now and generate the full Elementor JSON:`;
}

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

function reassignIds(obj: unknown): unknown {
  if (Array.isArray(obj)) return obj.map(reassignIds);
  if (obj && typeof obj === 'object') {
    const o = obj as Record<string, unknown>;
    const result: Record<string, unknown> = {};
    for (const key of Object.keys(o)) {
      if (key === 'id' && typeof o[key] === 'string' && (o[key] as string).length >= 6) {
        result[key] = generateId();
      } else {
        result[key] = reassignIds(o[key]);
      }
    }
    return result;
  }
  return obj;
}

function extractJson(raw: string): string {
  let text = raw.replace(/^```(?:json)?\s*/im, '').replace(/\s*```\s*$/im, '').trim();
  const start = text.indexOf('{');
  const end = text.lastIndexOf('}');
  if (start !== -1 && end !== -1 && end > start) {
    text = text.substring(start, end + 1);
  }
  return text;
}

function countWidgets(elements: unknown[]): number {
  let count = 0;
  for (const el of elements) {
    if (!el || typeof el !== 'object') continue;
    const e = el as Record<string, unknown>;
    if (e.elType === 'widget') count++;
    if (Array.isArray(e.elements)) count += countWidgets(e.elements as unknown[]);
  }
  return count;
}

export async function generateElementorJSON(
  imageBase64: string,
  mimeType: string,
  versionDef: VersionDefinition
): Promise<GenerationResult> {
  const mediaType = mimeType as 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';

  const message = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 8192,
    system: 'You are an expert Elementor Pro developer. Your entire response must be a single raw JSON object. No markdown. No code fences. No explanation. Start with { and end with }.',
    messages: [
      {
        role: 'user',
        content: [
          { type: 'image', source: { type: 'base64', media_type: mediaType, data: imageBase64 } },
          { type: 'text', text: buildPrompt(versionDef) },
        ],
      },
    ],
  });

  const rawText = message.content[0].type === 'text' ? message.content[0].text : '';
  const cleaned = extractJson(rawText);

  let parsed: Record<string, unknown>;
  try {
    parsed = JSON.parse(cleaned);
  } catch {
    console.error('[GenerateElementorJSON] JSON parse failed. Preview:', rawText.substring(0, 500));
    throw new Error('Claude returned invalid JSON. Try again with a clearer screenshot.');
  }

  // Re-assign IDs to avoid collisions on repeated imports
  const withFreshIds = reassignIds(parsed) as Record<string, unknown>;

  const content = Array.isArray(withFreshIds.content) ? withFreshIds.content : [];
  const title = typeof withFreshIds.title === 'string' ? withFreshIds.title : 'Generated Page';

  const template: ElementorTemplate = {
    version: '0.4',
    title,
    type: 'page',
    page_settings: (withFreshIds.page_settings as ElementorTemplate['page_settings']) ?? [],
    content: content as ElementorTemplate['content'],
  };

  const warnings: string[] = [];
  if (content.length === 0) warnings.push('No content sections were generated. The screenshot may be unclear.');

  return {
    template,
    targetVersion: versionDef.version,
    warnings,
    confidence: content.length > 0 ? 0.85 : 0.2,
    metadata: {
      sectionsCount: content.length,
      widgetsCount: countWidgets(content),
      usesContainers: true,
      generatedAt: new Date().toISOString(),
    },
  };
}
