# apps/aroflo_connector_app/ui_automation_zones/core/config.py
import os
from dataclasses import dataclass
from pathlib import Path
from argparse import Namespace
from typing import List

from .paths import DEFAULT_STATE_FILE, ARTIFACTS_DIR, STATE_DIR


@dataclass(frozen=True)
class RunConfig:
    # Multi-tenant / session runtime
    tenant_id: str
    reuse_session: bool
    keep_open: bool

    # Users module
    user_email: str

    # Preferred: docs spec
    user_docs: List[str]

    # Legacy: index-based
    user_files: List[str]
    user_comments: List[str]
    user_filters: List[str]

    base_url: str
    username: str
    password: str
    headless: bool
    slow_mo_ms: int
    step: bool
    pause_on_mfa: bool
    state_file: Path
    artifacts_dir: Path

    # Timesheet targeting + delete behavior
    timesheet_date: str
    timesheet_bu: str
    timesheet_user_id: str
    timesheet_user_name: str
    delete_all: bool
    include_protected: bool
    timesheet_rows: List[dict]


def _safe_env(name: str, default: str = "") -> str:
    return os.environ.get(name, default).strip()


def _bool_env(name: str, default: bool) -> bool:
    val = _safe_env(name)
    if not val:
        return default
    return val.lower() in ("1", "true", "yes", "y", "on")


def _int_env(name: str, default: int) -> int:
    try:
        return int(_safe_env(name))
    except Exception:
        return default


def _parse_row_spec(spec: str) -> dict:
    # hours=5;overhead=Admin Duties;worktype=NT;tracking=ADMIN;note=...
    out: dict = {}
    for part in spec.split(";"):
        part = part.strip()
        if not part:
            continue
        if "=" not in part:
            raise SystemExit(f"Invalid --row token (expected key=value): {part!r}")
        k, v = part.split("=", 1)
        out[k.strip().lower()] = v.strip()

    # Required
    if not out.get("hours"):
        raise SystemExit(f"--row missing hours: {spec}")
    if not out.get("overhead"):
        raise SystemExit(f"--row missing overhead: {spec}")

    # Defaults
    out.setdefault("worktype", "NT")
    out.setdefault("tracking", "ADMIN")
    out.setdefault("note", "")

    return out


def _tenant_state_path(tenant_id: str) -> Path:
    """
    state/tenants/<tenant_id>.storageState.json
    """
    tenants_dir = STATE_DIR / "tenants"
    tenants_dir.mkdir(parents=True, exist_ok=True)
    # tenant_id puede tener '=' y cosas raras; lo normalizamos un poco para filename
    safe = tenant_id.replace("/", "_").replace("\\", "_")
    return tenants_dir / f"{safe}.storageState.json"


def build_config(args: Namespace) -> RunConfig:
    base_url = (
        (getattr(args, "base_url", None) or _safe_env("AROFLO_UI_BASE_URL") or _safe_env("AROFLO_BASE_URL"))
        .rstrip("/")
    )

    username = getattr(args, "username", None) or _safe_env("AROFLO_USERNAME")
    password = getattr(args, "password", None) or _safe_env("AROFLO_PASSWORD")

    if not base_url:
        raise SystemExit("Missing AROFLO_UI_BASE_URL (or pass --base-url)")
    if not username:
        raise SystemExit("Missing AROFLO_USERNAME")
    if not password:
        raise SystemExit("Missing AROFLO_PASSWORD")

    # Session flags
    tenant_id = (getattr(args, "tenant_id", "") or "").strip()
    reuse_session = bool(getattr(args, "reuse_session", False))
    keep_open = bool(getattr(args, "keep_open", False))

    # UI runtime options
    headless = args.headless if getattr(args, "headless", None) is not None else _bool_env("AROFLO_UI_HEADLESS", True)
    slow_mo_ms = args.slow_mo_ms if getattr(args, "slow_mo_ms", None) is not None else _int_env("AROFLO_UI_SLOW_MO_MS", 0)

    # Paths
    artifacts_dir = Path(args.artifacts_dir).resolve() if getattr(args, "artifacts_dir", None) else ARTIFACTS_DIR

    # state_file: prioridad -> CLI -> tenant -> default
    if getattr(args, "state_file", None):
        state_file = Path(args.state_file).resolve()
    elif tenant_id:
        state_file = _tenant_state_path(tenant_id)
    else:
        state_file = DEFAULT_STATE_FILE

    # Users: email + docs
    user_email = (getattr(args, "user_email", "") or "").strip()
    user_docs = [s.strip() for s in (getattr(args, "doc", None) or []) if (s or "").strip()]

    # Legacy doc flags (compat)
    user_files = [s.strip() for s in (getattr(args, "file", None) or []) if (s or "").strip()]
    user_comments = [s for s in (getattr(args, "comment", None) or [])]
    user_filters = [s for s in (getattr(args, "filter", None) or [])]

    # Timesheets
    timesheet_date = (getattr(args, "timesheet_date", "") or "").strip()
    # Prefer explicit timesheet_bu; fallback to generic --bu
    timesheet_bu = (getattr(args, "timesheet_bu", "") or "").strip()
    if not timesheet_bu:
        timesheet_bu = (getattr(args, "bu", "") or "").strip()
    timesheet_user_id = (getattr(args, "timesheet_user_id", "") or "").strip()
    timesheet_user_name = (getattr(args, "timesheet_user_name", "") or "").strip()

    delete_all = bool(getattr(args, "delete_all", False))
    include_protected = bool(getattr(args, "include_protected", False))

    rows_raw = getattr(args, "row", None) or []
    timesheet_rows = [_parse_row_spec(s) for s in rows_raw]

    return RunConfig(
        tenant_id=tenant_id,
        reuse_session=reuse_session,
        keep_open=keep_open,

        user_email=user_email,
        user_docs=user_docs,
        user_files=user_files,
        user_comments=user_comments,
        user_filters=user_filters,

        base_url=base_url,
        username=username,
        password=password,
        headless=bool(headless),
        slow_mo_ms=max(0, int(slow_mo_ms)),
        step=bool(getattr(args, "step", False)),
        pause_on_mfa=bool(getattr(args, "pause_on_mfa", False)),
        state_file=state_file,
        artifacts_dir=artifacts_dir,

        timesheet_date=timesheet_date,
        timesheet_bu=timesheet_bu,
        timesheet_user_id=timesheet_user_id,
        timesheet_user_name=timesheet_user_name,
        delete_all=delete_all,
        include_protected=include_protected,
        timesheet_rows=timesheet_rows,
    )
