"""SEO Generator for LandingForge."""
import json
from datetime import date


class SEOGenerator:
    """Generates SEO-related files: sitemap, robots.txt, .htaccess, manifest, browserconfig."""

    def __init__(self, config: dict):
        self.config = config
        self.site = config["site"]
        self.languages = config.get("languages", {})
        self.deployment = config.get("deployment", {})
        self.design = config.get("design", {})

    def _base_url(self) -> str:
        return f"https://{self.site['domain']}"

    def generate_sitemap(self) -> str:
        base = self._base_url()
        today = date.today().isoformat()
        supported = self.languages.get("supported", [])
        default_lang = self.languages.get("default", "en")

        pages = [
            ("", "1.0", "weekly"),
            ("about.html", "0.8", "monthly"),
            ("privacy.html", "0.3", "yearly"),
            ("terms.html", "0.3", "yearly"),
            ("cookies.html", "0.3", "yearly"),
        ]

        lines = ['<?xml version="1.0" encoding="UTF-8"?>']
        lines.append('<urlset')
        lines.append('  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
        lines.append('  xmlns:xhtml="http://www.w3.org/1999/xhtml">')

        for path, priority, changefreq in pages:
            loc = f"{base}/{path}" if path else f"{base}/"
            lines.append("  <url>")
            lines.append(f"    <loc>{loc}</loc>")
            lines.append(f"    <lastmod>{today}</lastmod>")
            lines.append(f"    <changefreq>{changefreq}</changefreq>")
            lines.append(f"    <priority>{priority}</priority>")
            # hreflang alternates
            for lang in supported:
                code = lang["code"]
                if code == default_lang:
                    href = loc
                else:
                    base_path = path if path else ""
                    href = f"{base}/lang/{code}/{base_path}" if base_path else f"{base}/lang/{code}/"
                lines.append(f'    <xhtml:link rel="alternate" hreflang="{code}" href="{href}"/>')
            lines.append(f'    <xhtml:link rel="alternate" hreflang="x-default" href="{loc}"/>')
            lines.append("  </url>")

        lines.append("</urlset>")
        return "\n".join(lines)

    def generate_robots(self) -> str:
        base = self._base_url()
        return f"""User-agent: *
Allow: /
Disallow: /includes/
Disallow: /deploy/
Disallow: /assets/fonts/
Crawl-delay: 1

User-agent: Googlebot
Allow: /
Disallow: /includes/
Disallow: /deploy/

User-agent: Bingbot
Allow: /
Disallow: /includes/
Disallow: /deploy/

User-agent: Yandex
Allow: /
Disallow: /includes/
Disallow: /deploy/

User-agent: Baiduspider
Allow: /
Disallow: /includes/
Disallow: /deploy/

Sitemap: {base}/sitemap.xml
"""

    def generate_htaccess(self) -> str:
        domain = self.site["domain"]
        apache_cfg = self.deployment.get("apache", {})
        cache_max_age = apache_cfg.get("cache_max_age", 2592000)
        return f"""# =====================================================
# LandingForge — .htaccess
# =====================================================

Options -Indexes +FollowSymLinks
DirectoryIndex index.php index.html

# ── HTTPS Redirect ────────────────────────────────
RewriteEngine On
RewriteCond %{{HTTPS}} off
RewriteRule ^ https://%{{HTTP_HOST}}%{{REQUEST_URI}} [R=301,L]

# ── Force www ─────────────────────────────────────
RewriteCond %{{HTTP_HOST}} !^www\\.
RewriteRule ^ https://www.{domain}%{{REQUEST_URI}} [R=301,L]

# ── Remove trailing slash ─────────────────────────
RewriteCond %{{REQUEST_FILENAME}} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]

# ── Clean URLs (.html extension optional) ─────────
RewriteCond %{{REQUEST_FILENAME}} !-f
RewriteCond %{{REQUEST_FILENAME}} !-d
RewriteCond %{{REQUEST_FILENAME}}.html -f
RewriteRule ^(.+)$ $1.html [L]

# ── Security Headers ──────────────────────────────
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-XSS-Protection "1; mode=block"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

# ── Browser Caching ───────────────────────────────
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/html                "access plus 1 hour"
  ExpiresByType text/css                 "access plus {cache_max_age} seconds"
  ExpiresByType application/javascript   "access plus {cache_max_age} seconds"
  ExpiresByType image/webp               "access plus {cache_max_age} seconds"
  ExpiresByType image/jpeg               "access plus {cache_max_age} seconds"
  ExpiresByType image/png                "access plus {cache_max_age} seconds"
  ExpiresByType image/svg+xml            "access plus {cache_max_age} seconds"
  ExpiresByType image/x-icon             "access plus {cache_max_age} seconds"
  ExpiresByType font/woff2               "access plus {cache_max_age} seconds"
  ExpiresByType application/font-woff2   "access plus {cache_max_age} seconds"
  ExpiresByType application/manifest+json "access plus 1 week"
</IfModule>

# ── GZip Compression ─────────────────────────────
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css application/javascript
  AddOutputFilterByType DEFLATE image/svg+xml application/json
  AddOutputFilterByType DEFLATE application/font-woff2 font/woff2
  AddOutputFilterByType DEFLATE application/xml text/xml
</IfModule>

# ── Block Sensitive Files ─────────────────────────
<FilesMatch "(\\.yaml|\\.yml|\\.env|\\.git|\\.htpasswd|composer\\.json|package\\.json)$">
  Require all denied
</FilesMatch>

# ── Custom Error Pages ────────────────────────────
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

# ── PHP settings (if PHP is available) ───────────
<IfModule mod_php.c>
  php_value upload_max_filesize 16M
  php_value post_max_size 16M
</IfModule>
"""

    def generate_manifest(self) -> str:
        brand = self.site["brand_name"]
        tagline = self.site.get("tagline", "")
        colors = self.design.get("colors", {})
        bg_color = colors.get("background_primary", "#0a0a1a")
        accent = colors.get("accent_primary", "#6c5ce7")
        domain = self.site["domain"]
        manifest = {
            "name": brand,
            "short_name": brand[:12],
            "description": f"{brand} — {tagline}",
            "start_url": "/",
            "display": "standalone",
            "orientation": "portrait-primary",
            "background_color": bg_color,
            "theme_color": accent,
            "lang": self.languages.get("default", "en"),
            "scope": "/",
            "icons": [
                {
                    "src": "/assets/images/favicon-16x16.png",
                    "sizes": "16x16",
                    "type": "image/png"
                },
                {
                    "src": "/assets/images/favicon-32x32.png",
                    "sizes": "32x32",
                    "type": "image/png"
                },
                {
                    "src": "/assets/images/apple-touch-icon.png",
                    "sizes": "180x180",
                    "type": "image/png"
                }
            ],
            "categories": ["productivity", "utilities"],
            "screenshots": []
        }
        return json.dumps(manifest, indent=2, ensure_ascii=False)

    def generate_browserconfig(self) -> str:
        colors = self.design.get("colors", {})
        accent = colors.get("accent_primary", "#6c5ce7")
        return f"""<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
  <msapplication>
    <tile>
      <square150x150logo src="/assets/images/favicon-32x32.png"/>
      <TileColor>{accent}</TileColor>
    </tile>
  </msapplication>
</browserconfig>
"""
