"""
Data transformation utilities for Setmore entities.
Pure functions with no side effects.
"""

import hashlib
from datetime import datetime, timezone
from typing import Optional, Dict, Any


def parse_iso_timestamp(ts_str: Optional[str]) -> Optional[datetime]:
    """
    Parse ISO 8601 timestamp string to datetime with UTC timezone.
    
    Handles formats: 2021-02-19T19:00Z or 2021-02-19T19:00:00+00:00
    """
    if not ts_str:
        return None
    try:
        ts = ts_str.replace("Z", "+00:00")
        dt = datetime.fromisoformat(ts)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)
        return dt
    except (ValueError, TypeError):
        return None


def generate_extraction_id(window_start: datetime, window_end: datetime) -> str:
    """
    Generate deterministic ID for extraction window.
    
    Uses MD5 hash of start+end timestamps for idempotency.
    """
    content = f"{window_start.isoformat()}_{window_end.isoformat()}"
    return hashlib.md5(content.encode()).hexdigest()[:12]


def flatten_appointment(
    appt: Dict[str, Any],
    source_file: str,
    extraction_id: str,
    ingestion_timestamp: Optional[datetime] = None,
) -> Dict[str, Any]:
    """
    Flatten nested appointment structure for tabular storage.
    
    Args:
        appt: Raw appointment dict from Setmore API
        source_file: Identifier for source tracking
        extraction_id: Unique ID for this extraction batch
        ingestion_timestamp: Optional timestamp (defaults to now)
    """
    customer = appt.get("customer", {}) or {}
    start_time = parse_iso_timestamp(appt.get("start_time"))
    end_time = parse_iso_timestamp(appt.get("end_time"))
    date_key = start_time.strftime("%Y-%m-%d") if start_time else "unknown"
    
    cost_raw = appt.get("cost")
    cost = float(cost_raw) if cost_raw is not None else None
    
    return {
        "key": appt.get("key"),
        "start_time": start_time,
        "end_time": end_time,
        "duration": appt.get("duration"),
        "staff_key": appt.get("staff_key"),
        "service_key": appt.get("service_key"),
        "customer_key": appt.get("customer_key"),
        "cost": cost,
        "currency": appt.get("currency"),
        "comment": appt.get("comment"),
        "label": appt.get("label"),
        "customer_first_name": customer.get("first_name"),
        "customer_last_name": customer.get("last_name"),
        "customer_email": customer.get("email_id"),
        "customer_phone": customer.get("cell_phone"),
        "ingestion_timestamp": ingestion_timestamp or datetime.now(timezone.utc),
        "date_key": date_key,
        "source_file": source_file,
        "extraction_id": extraction_id,
    }


def process_staff_record(
    staff: Dict[str, Any],
    source_file: str,
    extraction_id: str,
    ingestion_timestamp: Optional[datetime] = None,
) -> Dict[str, Any]:
    """Process staff record with metadata."""
    return {
        "key": staff.get("key"),
        "first_name": staff.get("first_name"),
        "last_name": staff.get("last_name"),
        "email_id": staff.get("email_id"),
        "country_code": staff.get("country_code"),
        "work_phone": staff.get("work_phone"),
        "image_url": staff.get("image_url"),
        "comment": staff.get("comment"),
        "ingestion_timestamp": ingestion_timestamp or datetime.now(timezone.utc),
        "source_file": source_file,
        "extraction_id": extraction_id,
    }


def process_service_record(
    svc: Dict[str, Any],
    source_file: str,
    extraction_id: str,
    ingestion_timestamp: Optional[datetime] = None,
) -> Dict[str, Any]:
    """Process service record with metadata."""
    cost_raw = svc.get("cost")
    cost = float(cost_raw) if cost_raw is not None else None
    
    return {
        "key": svc.get("key"),
        "service_name": svc.get("service_name"),
        "staff_keys": svc.get("staff_keys", []),
        "duration": svc.get("duration"),
        "buffer_duration": svc.get("buffer_duration", 0),
        "cost": cost,
        "currency": svc.get("currency"),
        "image_url": svc.get("image_url"),
        "description": svc.get("description"),
        "ingestion_timestamp": ingestion_timestamp or datetime.now(timezone.utc),
        "source_file": source_file,
        "extraction_id": extraction_id,
    }