from __future__ import annotations

import hashlib
import json
import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from pathlib import Path
from sqlite3 import Connection
from typing import Any


def utc_now() -> str:
    return datetime.now(timezone.utc).isoformat()


def stable_id(prefix: str, *parts: object) -> str:
    payload = "|".join(str(p or "").strip().lower() for p in parts)
    digest = hashlib.sha256(payload.encode("utf-8")).hexdigest()[:24]
    return f"{prefix}_{digest}"


def parse_bool(value: object, default: bool = False) -> int:
    if value is None or str(value).strip() == "":
        return 1 if default else 0
    return 1 if str(value).strip().lower() in {"1", "true", "yes", "ja", "y"} else 0


def clean(value: object) -> str:
    return str(value or "").strip()


def require_text(row: dict[str, Any], field: str, line: int) -> str:
    value = clean(row.get(field))
    if not value:
        raise ValueError(f"line {line}: {field} is required")
    return value


def source_hash(path: str | Path) -> str:
    data = Path(path).read_bytes()
    return hashlib.sha256(data).hexdigest()


@dataclass(frozen=True)
class ImportResult:
    import_session_id: str
    import_type: str
    status: str
    rows_total: int
    rows_new: int
    rows_existing: int
    rows_failed: int
    errors: list[str] = field(default_factory=list)


def create_import_session(
    conn: Connection,
    *,
    import_type: str,
    source_filename: str,
    file_hash: str | None,
    status: str,
    rows_total: int,
    rows_imported: int,
    rows_failed: int,
    errors: list[str],
    notes: str | None = None,
) -> str:
    session_id = str(uuid.uuid4())
    now = utc_now()
    conn.execute(
        """
        INSERT INTO import_sessions(
            import_session_id, import_type, source_filename, source_hash, started_at,
            finished_at, status, rows_total, rows_imported, rows_failed, errors_json, notes
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        """,
        (
            session_id,
            import_type,
            source_filename,
            file_hash,
            now,
            now,
            status,
            rows_total,
            rows_imported,
            rows_failed,
            json.dumps(errors, ensure_ascii=False),
            notes,
        ),
    )
    conn.commit()
    return session_id
