from __future__ import annotations

from collections import defaultdict

from django.http import Http404, HttpResponse
from django.shortcuts import render
from django.utils import timezone

from .models import Service
from .seo_exports import (
    SeoPageEntry,
    build_absolute_url,
    canonical_path_from_markdown_path,
    get_company_contact_snapshot,
    get_page_entry,
    get_seo_page_inventory,
    markdown_path_for,
)


def _markdown_response(content: str, canonical_url: str) -> HttpResponse:
    response = HttpResponse(content, content_type="text/markdown; charset=utf-8")
    response.headers["Link"] = f'<{canonical_url}>; rel="canonical"'
    response.headers["X-Robots-Tag"] = "noindex, nofollow"
    return response


def _render_markdown_sections(entry, request) -> str:
    region_path = entry.path.strip("/").split("/", 1)
    region_code = region_path[0] if region_path and region_path[0] in {"ca", "uae", "ireland"} else None

    lines = [
        f"# {entry.title}",
        "",
        f"Canonical URL: {build_absolute_url(entry.path, request)}",
        f"Markdown URL: {build_absolute_url(markdown_path_for(entry.path), request)}",
        f"Section: {entry.section}",
        f"Page Type: {entry.content_type}",
    ]
    if entry.lastmod:
        lines.append(f"Last Updated: {timezone.localtime(entry.lastmod).isoformat()}")
    lines.extend(["", "## Summary", "", entry.description or "No summary available."])

    if entry.body:
        lines.extend(["", "## Main Content", "", entry.body])

    if entry.content_type in {"service-index", "sector-page"}:
        services = Service.objects.filter(is_published=True).prefetch_related("regions").order_by("order", "title")
        service_lines = []
        for service in services:
            if region_code and service.regions.exists() and not service.regions.filter(code=region_code, is_active=True).exists():
                continue
            service_lines.append(
                f"- [{service.title}]({build_absolute_url('/' + ('/'.join([region_code]) + '/' if region_code else '') + 'services/' + service.slug + '/', request)})"
            )
        if service_lines:
            lines.extend(["", "## Related Services", ""])
            lines.extend(service_lines[:20])

    if entry.content_type == "contact":
        contact = get_company_contact_snapshot()
        lines.extend(
            [
                "",
                "## Contact",
                "",
                f"- Company: {contact['company_name']}",
                f"- Email: {contact['email']}",
                f"- Phone: {contact['phone']}",
                f"- Address: {contact['address']}",
            ]
        )

    return "\n".join(lines).strip() + "\n"


def llms_txt_view(request) -> HttpResponse:
    inventory = get_seo_page_inventory()
    grouped = defaultdict(list)
    for entry in inventory:
        grouped[entry.section].append(entry)

    contact = get_company_contact_snapshot()
    lines = [
        "Site: Xinfinity Group",
        f"Primary domain: {build_absolute_url('/', request)}",
        "Purpose: Commercial security, cleaning, facilities management, and sector support services.",
        "Preferred canonical format: HTML pages are canonical; markdown mirrors provide AI-friendly and accessibility-friendly alternate representations.",
        "Markdown mirror convention: Add .md to any canonical content URL. The homepage mirror is /index.md.",
        f"XML sitemap: {build_absolute_url('/sitemap.xml', request)}",
        f"LLMs file: {build_absolute_url('/llms.txt', request)}",
        "",
        "Company contact:",
        f"- Name: {contact['company_name']}",
        f"- Email: {contact['email']}",
        f"- Phone: {contact['phone']}",
        f"- Address: {contact['address']}",
        "",
        "Crawl guidance:",
        "- Prefer canonical HTML URLs for public indexing.",
        "- Use markdown mirrors when plain-text or markdown content is preferred.",
        "- Regional content exists for Canada, UAE, and Ireland under /ca/, /uae/, and /ireland/.",
        "- UK default content is served from the root path, with UK city landing pages under /city/<slug>/.",
        "",
        "Content inventory:",
    ]

    for section in sorted(grouped.keys()):
        lines.append(f"{section}:")
        for entry in grouped[section]:
            lines.append(f"- {build_absolute_url(entry.path, request)}")
            lines.append(f"  Title: {entry.title}")
            lines.append(f"  Summary: {entry.description}")
            lines.append(f"  Markdown: {build_absolute_url(markdown_path_for(entry.path), request)}")
        lines.append("")

    response = HttpResponse("\n".join(lines).strip() + "\n", content_type="text/plain; charset=utf-8")
    response.headers["X-Robots-Tag"] = "index, follow"
    return response


def markdown_mirror_view(request, mirror_path: str = "") -> HttpResponse:
    canonical_path = canonical_path_from_markdown_path(mirror_path)
    entry = get_page_entry(canonical_path)
    if not entry:
        raise Http404("Markdown mirror not found")
    return _markdown_response(_render_markdown_sections(entry, request), build_absolute_url(canonical_path, request))


def sitemap_xml_view(request) -> HttpResponse:
    entries = get_seo_page_inventory()
    # Note: Removed /llms.txt from sitemap as it's not a webpage
    # llms.txt is discoverable via itself (/llms.txt) and robots.txt
    serialized_entries = [
        {
            "loc": build_absolute_url(entry.path, request),
            "lastmod": entry.lastmod,
            "changefreq": entry.changefreq,
            "priority": entry.priority,
        }
        for entry in entries
    ]
    response = render(request, "sitemap.xml", {"entries": serialized_entries})
    response["Content-Type"] = "application/xml; charset=utf-8"
    return response


def robots_txt_view(request) -> HttpResponse:
    lines = [
        "User-agent: *",
        "Allow: /",
        "Disallow: /admin/",
        "Disallow: /private/",
        "Disallow: /*.md",
        f"Sitemap: {build_absolute_url('/sitemap.xml', request)}",
    ]
    return HttpResponse("\n".join(lines) + "\n", content_type="text/plain; charset=utf-8")
