import re
from typing import Optional

from datatypes.magicplan.api.response import PlanSummary

_UK_POSTCODE_RE = re.compile(r"[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}", re.IGNORECASE)


def _extract_postcode(address: str) -> str | None:
    match = _UK_POSTCODE_RE.search(address)
    if match is None:
        return None
    return match.group().replace(" ", "").upper()


def _normalize_postcode(postcode: str) -> str:
    return postcode.replace(" ", "").upper()


def find_matching_plan(plans: list[PlanSummary], address: str) -> Optional[PlanSummary]:
    postcode = _extract_postcode(address)
    if postcode is None:
        return None

    address_lower = address.lower()

    for plan in plans:
        if plan.address is None:
            continue

        plan_postcode = plan.address.postal_code
        if plan_postcode is None:
            continue

        if _normalize_postcode(plan_postcode) != postcode:
            continue

        street_parts = [
            p for p in [plan.address.street_number, plan.address.street] if p
        ]
        plan_street = " ".join(street_parts).lower()

        if plan_street and plan_street in address_lower:
            return plan

    return None
