from __future__ import annotations

import enum

from sqlalchemy import Boolean, ForeignKey, Integer, JSON, String, Text
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base, TimestampMixin, UUIDMixin


class ReportTemplate(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "report_templates"

    template_key: Mapped[str] = mapped_column(String(120), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(180))
    version: Mapped[str] = mapped_column(String(40))
    validation_type: Mapped[str] = mapped_column(String(120), index=True)
    reference_path: Mapped[str] = mapped_column(String(500))
    active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)


class TextBlock(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "text_blocks"

    template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True)
    block_key: Mapped[str] = mapped_column(String(160), index=True)
    title: Mapped[str] = mapped_column(String(240))
    content: Mapped[str] = mapped_column(Text)
    order_index: Mapped[int] = mapped_column(Integer, default=0)
    version: Mapped[str] = mapped_column(String(40), default="1.0")
    active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)


class ReportSection(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "report_sections"

    template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True)
    section_key: Mapped[str] = mapped_column(String(160), index=True)
    number: Mapped[str | None] = mapped_column(String(40))
    title: Mapped[str] = mapped_column(String(240))
    order_index: Mapped[int] = mapped_column(Integer, default=0)
    page_break_before: Mapped[bool] = mapped_column(Boolean, default=False)
    active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)


class ChecklistTemplate(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "checklist_templates"

    template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True)
    checklist_key: Mapped[str] = mapped_column(String(160), index=True)
    title: Mapped[str] = mapped_column(String(240))
    columns: Mapped[list[str]] = mapped_column(JSON, default=list)
    items: Mapped[list[dict]] = mapped_column(JSON, default=list)
    order_index: Mapped[int] = mapped_column(Integer, default=0)
    active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)


class MeasurementImportStatus(str, enum.Enum):
    uploaded = "HOCHGELADEN"
    analyzing = "ANALYSE_LAEUFT"
    preview_ready = "VORSCHAU_BEREIT"
    confirmed = "BESTAETIGT"
    error = "FEHLER"
    attachment_only = "NUR_ANLAGE"


class MeasurementImportType(str, enum.Enum):
    winlog_csv = "WINLOG_CSV"
    winlog_pdf = "WINLOG_PDF"
    winlog_attachment_only = "WINLOG_ATTACHMENT_ONLY"


class MeasurementImport(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "measurement_imports"

    validation_id: Mapped[str] = mapped_column(ForeignKey("validations.id"), index=True)
    import_type: Mapped[str] = mapped_column(String(60), index=True)
    original_filename: Mapped[str] = mapped_column(String(255))
    storage_path: Mapped[str] = mapped_column(String(500))
    sha256: Mapped[str] = mapped_column(String(64), index=True)
    parser_version: Mapped[str] = mapped_column(String(40))
    status: Mapped[str] = mapped_column(String(60), index=True)


class MeasurementImportValue(Base, UUIDMixin, TimestampMixin):
    __tablename__ = "measurement_import_values"

    import_id: Mapped[str] = mapped_column(ForeignKey("measurement_imports.id"), index=True)
    test_run: Mapped[str] = mapped_column(String(120), index=True)
    field_name: Mapped[str] = mapped_column(String(120), index=True)
    raw_value: Mapped[str | None] = mapped_column(Text)
    normalized_value: Mapped[str | None] = mapped_column(String(180))
    unit: Mapped[str | None] = mapped_column(String(40))
    source_page: Mapped[int | None] = mapped_column(Integer)
    source_text: Mapped[str | None] = mapped_column(Text)
    confidence: Mapped[int] = mapped_column(Integer, default=0)
    confirmed: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
    corrected_value: Mapped[str | None] = mapped_column(String(180))
