from __future__ import annotations

import json
import re

from resume_agent.models import ContactInfo, TailoringPackage

_INLINE_EVIDENCE_RE = re.compile(
    r"""
    \s*
    (?:
        \[\s*(?:evidence\s*:?\s*)?F\d+(?:\s*[,;/]\s*F\d+)*\s*\]
      | \(\s*(?:evidence\s*:?\s*)?F\d+(?:\s*[,;/]\s*F\d+)*\s*\)
      | 【\s*(?:evidence\s*:?\s*)?F\d+(?:\s*[,;/]\s*F\d+)*\s*】
    )
    """,
    re.IGNORECASE | re.VERBOSE,
)
_TRAILING_EVIDENCE_RE = re.compile(
    r"\s*(?:[-–—|]\s*)?(?:evidence|sources?)\s*:\s*"
    r"F\d+(?:\s*[,;/]\s*F\d+)*\s*$",
    re.IGNORECASE,
)
_EVIDENCE_COMMENT_RE = re.compile(
    r"\s*<!--\s*(?:Signal\s+)?evidence\s*:.*?-->\s*",
    re.IGNORECASE,
)


def _candidate_text(text: str) -> str:
    """Remove internal evidence notation before candidate-facing rendering."""
    text = _EVIDENCE_COMMENT_RE.sub(" ", text)
    text = _INLINE_EVIDENCE_RE.sub("", text)
    text = _TRAILING_EVIDENCE_RE.sub("", text)
    return re.sub(r"[ \t]+", " ", text).strip()


def _contact_line(contact: ContactInfo) -> str:
    values = [
        contact.location,
        contact.email,
        contact.phone,
        contact.linkedin,
        contact.website,
    ]
    return " | ".join(value for value in values if value)


def render_resume(package: TailoringPackage, include_evidence: bool = False) -> str:
    resume = package.resume
    lines = [f"# {resume.contact.full_name}", resume.headline]
    contact = _contact_line(resume.contact)
    if contact:
        lines.append(contact)

    lines.extend(["", "## Professional Summary", ""])
    for item in resume.summary:
        suffix = (
            f" <!-- evidence: {', '.join(item.evidence_ids)} -->"
            if include_evidence and item.evidence_ids
            else ""
        )
        lines.append(f"- {_candidate_text(item.text)}{suffix}")

    for section in resume.sections:
        lines.extend(["", f"## {section.title}", ""])
        for item in section.items:
            suffix = (
                f" <!-- evidence: {', '.join(item.evidence_ids)} -->"
                if include_evidence and item.evidence_ids
                else ""
            )
            lines.append(f"- {_candidate_text(item.text)}{suffix}")

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


def render_report(package: TailoringPackage) -> str:
    lines = ["# Tailoring Report", ""]
    if package.job.role_title or package.job.company:
        lines.append(
            f"Target: {package.job.role_title or 'Unknown role'}"
            f" at {package.job.company or 'Unknown company'}"
        )
        lines.append("")

    groups = [
        ("Strong matches", package.match.strong_matches),
        ("Partial matches", package.match.partial_matches),
        ("Genuine gaps", package.match.genuine_gaps),
        ("Changes made", package.changes_made),
        ("Questions for you", package.questions_for_candidate),
        ("Warnings", package.warnings),
    ]
    for title, items in groups:
        lines.extend([f"## {title}", ""])
        lines.extend(f"- {item}" for item in items)
        if not items:
            lines.append("- None")
        lines.append("")
    return "\n".join(lines).strip() + "\n"


def render_ohmycv_resume(
    package: TailoringPackage,
    source_markdown: str,
    include_evidence: bool = False,
) -> str:
    """Render clean, native Oh My CV Markdown with preserved editor metadata."""
    front_matter_match = re.match(r"\A---\r?\n.*?\r?\n---\r?\n?", source_markdown, re.DOTALL)
    if front_matter_match:
        front_matter = front_matter_match.group(0).rstrip()
    else:
        front_matter = _ohmycv_front_matter(package.resume.contact)

    lines = [front_matter, "", "## Professional Summary", ""]
    summary = [_candidate_text(item.text) for item in package.resume.summary]
    summary = [item for item in summary if item]
    if summary:
        lines.append(" ".join(summary))

    for section in package.resume.sections:
        title = _candidate_text(section.title)
        items = [_candidate_text(item.text) for item in section.items]
        items = [item for item in items if item]
        if not title or not items:
            continue
        lines.extend(["", "", f"## {title}", ""])
        for item in section.items:
            clean_text = _candidate_text(item.text)
            if not clean_text:
                continue
            lines.append(f"- {clean_text}")
            if include_evidence and item.evidence_ids:
                lines.append(f"  <!-- Signal evidence: {', '.join(item.evidence_ids)} -->")

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


def _ohmycv_front_matter(contact: ContactInfo) -> str:
    """Create the header structure consumed by Oh My CV's native renderer."""
    lines = ["---", f"name: {json.dumps(contact.full_name, ensure_ascii=False)}"]
    header: list[tuple[str, str | None]] = []
    if contact.location:
        header.append((_header_text("tabler:map-pin", contact.location), None))
    if contact.phone:
        header.append((_header_text("tabler:phone", contact.phone), f"tel:{contact.phone}"))
    if contact.email:
        header.append((_header_text("tabler:mail", contact.email), f"mailto:{contact.email}"))
    if contact.linkedin:
        header.append(
            (
                _header_text("tabler:brand-linkedin", contact.linkedin),
                _absolute_url(contact.linkedin),
            )
        )
    if contact.website:
        header.append(
            (
                _header_text("tabler:world", contact.website),
                _absolute_url(contact.website),
            )
        )

    if header:
        lines.append("header:")
        for text, link in header:
            lines.append(f"  - text: {json.dumps(text, ensure_ascii=False)}")
            if link:
                lines.append(f"    link: {json.dumps(link, ensure_ascii=False)}")
    lines.append("---")
    return "\n".join(lines)


def _header_text(icon: str, value: str) -> str:
    return f'<span class="iconify" data-icon="{icon}"></span> {value}'


def _absolute_url(value: str) -> str:
    return value if re.match(r"https?://", value, re.IGNORECASE) else f"https://{value}"
