from typing import Optional

from sqlalchemy import Integer, Text, CheckConstraint
from sqlalchemy.orm import Mapped, mapped_column

from nhs_waiting_lists.models.base import Base


class Incomplete(Base):
    """
    Bucketed waiting times.
    """
    __tablename__ = "incomplete"

    # Primary key - includes commissioner to preserve all rows before grouping
    period: Mapped[str] = mapped_column(Text, primary_key=True)
    provider: Mapped[str] = mapped_column(Text, primary_key=True)
    treatment: Mapped[str] = mapped_column(Text, primary_key=True)

    # Waiting time buckets (0-104 weeks)
    gt_00_to_01_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_01_to_02_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_02_to_03_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_03_to_04_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_04_to_05_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_05_to_06_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_06_to_07_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_07_to_08_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_08_to_09_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_09_to_10_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_10_to_11_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_11_to_12_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_12_to_13_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_13_to_14_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_14_to_15_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_15_to_16_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_16_to_17_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_17_to_18_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_18_to_19_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_19_to_20_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_20_to_21_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_21_to_22_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_22_to_23_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_23_to_24_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_24_to_25_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_25_to_26_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_26_to_27_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_27_to_28_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_28_to_29_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_29_to_30_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_30_to_31_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_31_to_32_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_32_to_33_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_33_to_34_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_34_to_35_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_35_to_36_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_36_to_37_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_37_to_38_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_38_to_39_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_39_to_40_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_40_to_41_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_41_to_42_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_42_to_43_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_43_to_44_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_44_to_45_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_45_to_46_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_46_to_47_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_47_to_48_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_48_to_49_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_49_to_50_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_50_to_51_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_51_to_52_weeks: Mapped[Optional[int]] = mapped_column(Integer)

    # Extended buckets (52-104 weeks) - only in newer data (Apr 2021+)
    # For old data, these will be NULL and gt_52_weeks will be populated
    gt_52_to_53_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_53_to_54_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_54_to_55_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_55_to_56_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_56_to_57_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_57_to_58_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_58_to_59_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_59_to_60_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_60_to_61_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_61_to_62_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_62_to_63_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_63_to_64_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_64_to_65_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_65_to_66_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_66_to_67_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_67_to_68_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_68_to_69_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_69_to_70_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_70_to_71_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_71_to_72_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_72_to_73_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_73_to_74_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_74_to_75_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_75_to_76_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_76_to_77_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_77_to_78_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_78_to_79_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_79_to_80_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_80_to_81_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_81_to_82_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_82_to_83_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_83_to_84_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_84_to_85_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_85_to_86_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_86_to_87_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_87_to_88_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_88_to_89_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_89_to_90_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_90_to_91_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_91_to_92_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_92_to_93_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_93_to_94_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_94_to_95_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_95_to_96_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_96_to_97_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_97_to_98_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_98_to_99_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_99_to_100_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_100_to_101_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_101_to_102_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_102_to_103_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_103_to_104_weeks: Mapped[Optional[int]] = mapped_column(Integer)
    gt_104_weeks: Mapped[Optional[int]] = mapped_column(Integer)

    # Legacy bucket for old data (pre-Apr 2021)
    # In old CSVs this was the final bucket "52 weeks and greater"
    gt_52_weeks: Mapped[Optional[int]] = mapped_column(Integer)

    # synthetic fields
    wait_lt_18: Mapped[Optional[int]] = mapped_column(Integer)
    wait_gte_18: Mapped[Optional[int]] = mapped_column(Integer)
    wait_pct_lt_18: Mapped[Optional[int]] = mapped_column(Integer)
    wait_pct_gte_18: Mapped[Optional[int]] = mapped_column(Integer)

    # Summary columns
    total_all: Mapped[Optional[int]] = mapped_column(Integer)

    # QA/validation columns (computed during import for integrity checks)
    qa_wait_diff: Mapped[Optional[int]] = mapped_column(Integer)
    qa_wait_sum: Mapped[Optional[int]] = mapped_column(Integer)  # Sum of all wait buckets
    qa_diff_total: Mapped[Optional[int]] = mapped_column(Integer)  # wait_sum - total (should be ~0)
    qa_diff_total_all: Mapped[Optional[int]] = mapped_column(Integer)  # wait_sum - total_all + unknown (should be ~0)
