# retoor <retoor@molodetz.nl>
from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from devplacepy.services.jobs.isslop.acquisition.browser import RenderResult

DOM_INIT_SCRIPT = """
window.__isslop = {};
"""

DOM_EXTRACT_SCRIPT = r"""
() => {
  const safe = (fn, fallback) => { try { return fn(); } catch (e) { return fallback; } };
  const metaByName = (name) => safe(() => {
    const el = document.querySelector(`meta[name="${name}"]`);
    return el ? (el.getAttribute('content') || '') : '';
  }, '');
  const metaByProperty = (name) => safe(() => {
    const el = document.querySelector(`meta[property="${name}"]`);
    return el ? (el.getAttribute('content') || '') : '';
  }, '');
  const linkHref = (rel) => safe(() => {
    const el = document.querySelector(`link[rel="${rel}"]`);
    return el ? (el.getAttribute('href') || '') : '';
  }, '');
  const meta = {
    title: safe(() => (document.title || '').trim(), ''),
    generator: metaByName('generator'),
    description: metaByName('description'),
    ogImage: metaByProperty('og:image'),
    canonical: linkHref('canonical'),
    htmlLang: safe(() => document.documentElement.getAttribute('lang') || '', ''),
    favicon: safe(() => linkHref('icon') || linkHref('shortcut icon'), ''),
  };
  const badgeSelectors = [
    '#lovable-badge',
    '.replit-badge',
    '#base44-badge',
    '#__framer-badge-container',
    '[data-radix-root]',
    'iframe[src*="claudeusercontent.com"]',
  ];
  const badgeHits = {};
  badgeSelectors.forEach((sel) => {
    badgeHits[sel] = safe(() => !!document.querySelector(sel), false);
  });
  const headings = [];
  safe(() => {
    document.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach((h) => {
      if (headings.length >= 60) return;
      headings.push({
        level: parseInt(h.tagName.substring(1), 10),
        text: (h.textContent || '').trim().slice(0, 160),
      });
    });
  }, null);
  const landmarks = {
    main: safe(() => document.querySelectorAll('main').length, 0),
    nav: safe(() => document.querySelectorAll('nav').length, 0),
    header: safe(() => document.querySelectorAll('header').length, 0),
    footer: safe(() => document.querySelectorAll('footer').length, 0),
    article: safe(() => document.querySelectorAll('article').length, 0),
  };
  const images = [];
  safe(() => {
    document.querySelectorAll('img').forEach((img) => {
      if (images.length >= 100) return;
      images.push({
        src: img.getAttribute('src') || '',
        alt: img.getAttribute('alt') || '',
      });
    });
  }, null);
  const classCounts = {};
  safe(() => {
    document.querySelectorAll('[class]').forEach((el) => {
      const raw = el.getAttribute('class') || '';
      raw.split(/\s+/).filter(Boolean).forEach((token) => {
        classCounts[token] = (classCounts[token] || 0) + 1;
      });
    });
  }, null);
  const classNames = {};
  Object.keys(classCounts)
    .sort((a, b) => classCounts[b] - classCounts[a])
    .slice(0, 40)
    .forEach((token) => { classNames[token] = classCounts[token]; });
  const colorSample = (tag, el) => safe(() => {
    const style = getComputedStyle(el);
    return {
      tag: tag,
      backgroundImage: style.backgroundImage || '',
      backgroundColor: style.backgroundColor || '',
      color: style.color || '',
      boxShadow: style.boxShadow || '',
    };
  }, null);
  const colors = [];
  safe(() => {
    if (document.body) {
      const sample = colorSample('body', document.body);
      if (sample) colors.push(sample);
    }
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('h1,h2')).slice(0, 6).forEach((el) => {
      const sample = colorSample(el.tagName.toLowerCase(), el);
      if (sample) colors.push(sample);
    });
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('button, a.btn, [class*="btn"]')).slice(0, 10).forEach((el) => {
      const sample = colorSample(el.tagName.toLowerCase(), el);
      if (sample) colors.push(sample);
    });
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('nav, header')).slice(0, 4).forEach((el) => {
      const sample = colorSample(el.tagName.toLowerCase(), el);
      if (sample) colors.push(sample);
    });
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('[class*="hero"]')).slice(0, 4).forEach((el) => {
      const sample = colorSample(el.tagName.toLowerCase(), el);
      if (sample) colors.push(sample);
    });
  }, null);
  const fontSample = (tag, el) => safe(() => {
    const style = getComputedStyle(el);
    return {
      tag: tag,
      fontFamily: style.fontFamily || '',
      fontWeight: style.fontWeight || '',
      letterSpacing: style.letterSpacing || '',
      fontSize: style.fontSize || '',
      lineHeight: style.lineHeight || '',
    };
  }, null);
  const fonts = [];
  safe(() => {
    if (document.body) {
      const sample = fontSample('body', document.body);
      if (sample) fonts.push(sample);
    }
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('h1,h2,h3')).slice(0, 10).forEach((el) => {
      const sample = fontSample(el.tagName.toLowerCase(), el);
      if (sample) fonts.push(sample);
    });
  }, null);
  safe(() => {
    Array.from(document.querySelectorAll('p, button')).slice(0, 8).forEach((el) => {
      if (fonts.length >= 20) return;
      const sample = fontSample(el.tagName.toLowerCase(), el);
      if (sample) fonts.push(sample);
    });
  }, null);
  const scripts = [];
  safe(() => {
    document.querySelectorAll('script[src]').forEach((s) => {
      if (scripts.length >= 60) return;
      scripts.push(s.getAttribute('src') || '');
    });
  }, null);
  const links = [];
  safe(() => {
    document.querySelectorAll('link[href]').forEach((l) => {
      if (links.length >= 60) return;
      links.push(l.getAttribute('href') || '');
    });
  }, null);
  const wordCount = safe(() => {
    const text = document.body ? (document.body.innerText || '') : '';
    return text.split(/\s+/).filter(Boolean).length;
  }, 0);
  const deadAnchorCount = safe(() => document.querySelectorAll('a[href="#"]').length, 0);
  const jsonldCount = safe(() => document.querySelectorAll('script[type="application/ld+json"]').length, 0);
  const robotsMeta = metaByName('robots');
  return {
    meta: meta,
    badgeHits: badgeHits,
    headings: headings.slice(0, 60),
    landmarks: landmarks,
    images: images.slice(0, 100),
    classNames: classNames,
    colors: colors.slice(0, 30),
    fonts: fonts.slice(0, 20),
    jsonld: jsonldCount,
    scripts: scripts.slice(0, 60),
    links: links.slice(0, 60),
    wordCount: wordCount,
    deadAnchorCount: deadAnchorCount,
    robotsMeta: robotsMeta,
  };
}
"""


@dataclass(frozen=True)
class DomSnapshot:
    render: RenderResult
    dom: dict = field(default_factory=dict)
    console_warnings: list[str] = field(default_factory=list)
    console_errors: list[str] = field(default_factory=list)
    response_headers: dict[str, str] = field(default_factory=dict)
    resource_hosts: list[str] = field(default_factory=list)
    screenshot_bytes: bytes | None = None
