#!/usr/bin/env python3
"""Compare two UK FAnGR horse-breed measures for 2021 and 2025.

Source: Department for Environment, Food & Rural Affairs, UK FAnGR breed
inventory, 2025 release (CSV dated 2026-05-14):
https://assets.publishing.service.gov.uk/media/6a5a206e5ca06bf11ccb43d7/fangr_timeseries_20260514.csv

Usage:
    python3 analyze-uk-horse-registration-population.py \
        fangr_timeseries_20260514.csv uk-fangr-horse-2021-2025.csv
"""

import csv
import hashlib
import sys
from pathlib import Path

EXPECTED_SHA256 = "08a3e6aac3e7a86d9abc25fd7cd810d3be64f53c0820c78f7173b9e3968fda1e"
YEARS = ("2021", "2025")
VARIABLES = ("females", "fempop")
FIELDS = (
    "breed_name",
    "included",
    "exclusion_reason",
    "female_registrations_2021",
    "female_registrations_2025",
    "registration_change_pct",
    "breeding_females_2021",
    "breeding_females_2025",
    "breeding_population_change_pct",
    "opposite_direction",
    "opposite_over_5pct",
)


def percentage_change(start, end):
    return (end / start - 1) * 100


def analyze(source):
    digest = hashlib.sha256(source.read_bytes()).hexdigest()
    if digest != EXPECTED_SHA256:
        raise ValueError(f"Source CSV SHA-256 differs from the analyzed release: {digest}")

    with source.open(encoding="utf-8-sig", newline="") as handle:
        reader = csv.DictReader(handle)
        required = {"species", "breed_name", "native", "year", "population_variable", "values"}
        if not required.issubset(reader.fieldnames or []):
            raise ValueError("Source CSV is missing expected columns")
        source_rows = list(reader)

    horses = [row for row in source_rows if row["species"] == "Horses" and row["native"] == "Y"]
    breeds = sorted({row["breed_name"] for row in horses})
    by_key = {}
    for row in horses:
        key = (row["breed_name"], row["year"], row["population_variable"])
        if key in by_key:
            raise ValueError(f"Duplicate breed-year-variable row: {key}")
        by_key[key] = row["values"].strip()

    results = []
    for breed in breeds:
        values = {
            (year, variable): by_key.get((breed, year, variable), "")
            for year in YEARS
            for variable in VARIABLES
        }
        missing = [f"{year} {variable}" for (year, variable), value in values.items() if not value]
        result = {field: "" for field in FIELDS}
        result["breed_name"] = breed
        result["female_registrations_2021"] = values[("2021", "females")]
        result["female_registrations_2025"] = values[("2025", "females")]
        result["breeding_females_2021"] = values[("2021", "fempop")]
        result["breeding_females_2025"] = values[("2025", "fempop")]

        if missing:
            result["included"] = "no"
            result["exclusion_reason"] = "missing " + ", ".join(missing)
        else:
            counts = {key: float(value) for key, value in values.items()}
            if counts[("2021", "females")] <= 0 or counts[("2021", "fempop")] <= 0:
                result["included"] = "no"
                result["exclusion_reason"] = "zero 2021 denominator"
            else:
                registration_change = percentage_change(
                    counts[("2021", "females")], counts[("2025", "females")]
                )
                population_change = percentage_change(
                    counts[("2021", "fempop")], counts[("2025", "fempop")]
                )
                opposite = registration_change * population_change < 0
                result.update(
                    included="yes",
                    registration_change_pct=f"{registration_change:.1f}",
                    breeding_population_change_pct=f"{population_change:.1f}",
                    opposite_direction="yes" if opposite else "no",
                    opposite_over_5pct="yes"
                    if (registration_change > 5 and population_change < -5)
                    or (registration_change < -5 and population_change > 5)
                    else "no",
                )
        results.append(result)
    return results


def main():
    if len(sys.argv) != 3:
        raise SystemExit("Usage: analyze-uk-horse-registration-population.py SOURCE_CSV OUTPUT_CSV")
    results = analyze(Path(sys.argv[1]))
    with Path(sys.argv[2]).open("w", encoding="utf-8", newline="") as handle:
        writer = csv.DictWriter(handle, fieldnames=FIELDS)
        writer.writeheader()
        writer.writerows(results)
    included = [row for row in results if row["included"] == "yes"]
    print(
        f"Native horse breeds: {len(results)}; complete: {len(included)}; "
        f"opposite direction: {sum(row['opposite_direction'] == 'yes' for row in included)}; "
        f"opposite beyond 5% in both: {sum(row['opposite_over_5pct'] == 'yes' for row in included)}"
    )


if __name__ == "__main__":
    main()
