"""Seed data generator for demo mode.

Populates the demo data directory with sample entities on first run,
giving new users a realistic out-of-the-box experience without needing
real hardware.
"""

import json
from datetime import datetime, timezone
from pathlib import Path

from wled_controller.config import StorageConfig
from wled_controller.utils import get_logger

logger = get_logger(__name__)

# Fixed IDs so cross-references are stable
_DEVICE_IDS = {
    "strip": "device_demo0001",
    "matrix": "device_demo0002",
    "ring": "device_demo0003",
}

_TARGET_IDS = {
    "strip": "pt_demo0001",
    "matrix": "pt_demo0002",
}

_PS_IDS = {
    "main": "ps_demo0001",
    "secondary": "ps_demo0002",
}

_CSS_IDS = {
    "gradient": "css_demo0001",
    "cycle": "css_demo0002",
    "picture": "css_demo0003",
    "audio": "css_demo0004",
}

_AS_IDS = {
    "system": "as_demo0001",
    "mono": "as_demo0002",
}

_TPL_ID = "tpl_demo0001"

_SCENE_ID = "scene_demo0001"

_NOW = datetime.now(timezone.utc).isoformat()


def _write_store(path: Path, json_key: str, items: dict) -> None:
    """Write a store JSON file with version wrapper."""
    path.parent.mkdir(parents=True, exist_ok=True)
    data = {
        "version": "1.0.0",
        json_key: items,
    }
    path.write_text(json.dumps(data, indent=2), encoding="utf-8")
    logger.info(f"Seeded {len(items)} {json_key} -> {path}")


def _has_data(storage_config: StorageConfig) -> bool:
    """Check if any demo store file already has entities."""
    for field_name in storage_config.model_fields:
        value = getattr(storage_config, field_name)
        if not isinstance(value, str):
            continue
        p = Path(value)
        if p.exists() and p.stat().st_size > 20:
            # File exists and is non-trivial — check if it has entities
            try:
                raw = json.loads(p.read_text(encoding="utf-8"))
                for key, val in raw.items():
                    if key != "version" and isinstance(val, dict) and val:
                        return True
            except Exception:
                pass
    return False


def seed_demo_data(storage_config: StorageConfig) -> None:
    """Populate demo data directory with sample entities.

    Only runs when the demo data directory is empty (no existing entities).
    Must be called BEFORE store constructors run so they load the seeded data.
    """
    if _has_data(storage_config):
        logger.info("Demo data already exists — skipping seed")
        return

    logger.info("Seeding demo data for first-run experience")

    _seed_devices(Path(storage_config.devices_file))
    _seed_capture_templates(Path(storage_config.templates_file))
    _seed_output_targets(Path(storage_config.output_targets_file))
    _seed_picture_sources(Path(storage_config.picture_sources_file))
    _seed_color_strip_sources(Path(storage_config.color_strip_sources_file))
    _seed_audio_sources(Path(storage_config.audio_sources_file))
    _seed_scene_presets(Path(storage_config.scene_presets_file))

    logger.info("Demo seed data complete")


# ── Devices ────────────────────────────────────────────────────────

def _seed_devices(path: Path) -> None:
    devices = {
        _DEVICE_IDS["strip"]: {
            "id": _DEVICE_IDS["strip"],
            "name": "Demo LED Strip",
            "url": "demo://demo-strip",
            "led_count": 60,
            "enabled": True,
            "device_type": "demo",
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _DEVICE_IDS["matrix"]: {
            "id": _DEVICE_IDS["matrix"],
            "name": "Demo LED Matrix",
            "url": "demo://demo-matrix",
            "led_count": 256,
            "enabled": True,
            "device_type": "demo",
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _DEVICE_IDS["ring"]: {
            "id": _DEVICE_IDS["ring"],
            "name": "Demo LED Ring",
            "url": "demo://demo-ring",
            "led_count": 24,
            "enabled": True,
            "device_type": "demo",
            "created_at": _NOW,
            "updated_at": _NOW,
        },
    }
    _write_store(path, "devices", devices)


# ── Capture Templates ──────────────────────────────────────────────

def _seed_capture_templates(path: Path) -> None:
    templates = {
        _TPL_ID: {
            "id": _TPL_ID,
            "name": "Demo Capture",
            "engine_type": "demo",
            "engine_config": {},
            "description": "Default capture template using demo engine",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
        },
    }
    _write_store(path, "templates", templates)


# ── Output Targets ─────────────────────────────────────────────────

def _seed_output_targets(path: Path) -> None:
    targets = {
        _TARGET_IDS["strip"]: {
            "id": _TARGET_IDS["strip"],
            "name": "Strip — Gradient",
            "target_type": "led",
            "device_id": _DEVICE_IDS["strip"],
            "color_strip_source_id": _CSS_IDS["gradient"],
            "brightness_value_source_id": "",
            "fps": 30,
            "keepalive_interval": 1.0,
            "state_check_interval": 30,
            "min_brightness_threshold": 0,
            "adaptive_fps": False,
            "protocol": "ddp",
            "description": "Demo LED strip with gradient effect",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _TARGET_IDS["matrix"]: {
            "id": _TARGET_IDS["matrix"],
            "name": "Matrix — Screen Capture",
            "target_type": "led",
            "device_id": _DEVICE_IDS["matrix"],
            "color_strip_source_id": _CSS_IDS["picture"],
            "brightness_value_source_id": "",
            "fps": 30,
            "keepalive_interval": 1.0,
            "state_check_interval": 30,
            "min_brightness_threshold": 0,
            "adaptive_fps": False,
            "protocol": "ddp",
            "description": "Demo LED matrix with screen capture",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
        },
    }
    _write_store(path, "output_targets", targets)


# ── Picture Sources ────────────────────────────────────────────────

def _seed_picture_sources(path: Path) -> None:
    sources = {
        _PS_IDS["main"]: {
            "id": _PS_IDS["main"],
            "name": "Demo Display 1080p",
            "stream_type": "raw",
            "display_index": 0,
            "capture_template_id": _TPL_ID,
            "target_fps": 30,
            "description": "Virtual 1920x1080 display capture",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
            # Nulls for non-applicable subclass fields
            "source_stream_id": None,
            "postprocessing_template_id": None,
            "image_source": None,
            "url": None,
            "loop": None,
            "playback_speed": None,
            "start_time": None,
            "end_time": None,
            "resolution_limit": None,
            "clock_id": None,
        },
        _PS_IDS["secondary"]: {
            "id": _PS_IDS["secondary"],
            "name": "Demo Display 4K",
            "stream_type": "raw",
            "display_index": 1,
            "capture_template_id": _TPL_ID,
            "target_fps": 30,
            "description": "Virtual 3840x2160 display capture",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
            "source_stream_id": None,
            "postprocessing_template_id": None,
            "image_source": None,
            "url": None,
            "loop": None,
            "playback_speed": None,
            "start_time": None,
            "end_time": None,
            "resolution_limit": None,
            "clock_id": None,
        },
    }
    _write_store(path, "picture_sources", sources)


# ── Color Strip Sources ────────────────────────────────────────────

def _seed_color_strip_sources(path: Path) -> None:
    sources = {
        _CSS_IDS["gradient"]: {
            "id": _CSS_IDS["gradient"],
            "name": "Rainbow Gradient",
            "source_type": "gradient",
            "description": "Smooth rainbow gradient across all LEDs",
            "clock_id": None,
            "tags": ["demo"],
            "stops": [
                {"position": 0.0, "color": [255, 0, 0]},
                {"position": 0.25, "color": [255, 255, 0]},
                {"position": 0.5, "color": [0, 255, 0]},
                {"position": 0.75, "color": [0, 0, 255]},
                {"position": 1.0, "color": [255, 0, 255]},
            ],
            "animation": {"enabled": True, "type": "gradient_shift", "speed": 0.5},
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _CSS_IDS["cycle"]: {
            "id": _CSS_IDS["cycle"],
            "name": "Warm Color Cycle",
            "source_type": "color_cycle",
            "description": "Smoothly cycles through warm colors",
            "clock_id": None,
            "tags": ["demo"],
            "colors": [
                [255, 60, 0],
                [255, 140, 0],
                [255, 200, 50],
                [255, 100, 20],
            ],
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _CSS_IDS["picture"]: {
            "id": _CSS_IDS["picture"],
            "name": "Screen Capture — Main Display",
            "source_type": "picture",
            "description": "Captures colors from the main demo display",
            "clock_id": None,
            "tags": ["demo"],
            "picture_source_id": _PS_IDS["main"],
            "fps": 30,
            "smoothing": 0.3,
            "interpolation_mode": "average",
            "calibration": {
                "mode": "simple",
                "layout": "clockwise",
                "start_position": "bottom_left",
                "leds_top": 28,
                "leds_bottom": 28,
                "leds_left": 16,
                "leds_right": 16,
            },
            "led_count": 0,
            "created_at": _NOW,
            "updated_at": _NOW,
        },
        _CSS_IDS["audio"]: {
            "id": _CSS_IDS["audio"],
            "name": "Audio Spectrum",
            "source_type": "audio",
            "description": "Audio-reactive spectrum visualization",
            "clock_id": None,
            "tags": ["demo"],
            "visualization_mode": "spectrum",
            "audio_source_id": _AS_IDS["mono"],
            "sensitivity": 1.0,
            "smoothing": 0.3,
            "palette": "rainbow",
            "color": [0, 255, 0],
            "color_peak": [255, 0, 0],
            "led_count": 0,
            "mirror": False,
            "created_at": _NOW,
            "updated_at": _NOW,
        },
    }
    _write_store(path, "color_strip_sources", sources)


# ── Audio Sources ──────────────────────────────────────────────────

def _seed_audio_sources(path: Path) -> None:
    sources = {
        _AS_IDS["system"]: {
            "id": _AS_IDS["system"],
            "name": "Demo System Audio",
            "source_type": "multichannel",
            "device_index": 1,
            "is_loopback": True,
            "audio_template_id": None,
            "description": "Virtual system audio (loopback)",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
            # Forward-compat null fields
            "audio_source_id": None,
            "channel": None,
        },
        _AS_IDS["mono"]: {
            "id": _AS_IDS["mono"],
            "name": "Demo Audio — Mono",
            "source_type": "mono",
            "audio_source_id": _AS_IDS["system"],
            "channel": "mono",
            "description": "Mono mix of demo system audio",
            "tags": ["demo"],
            "created_at": _NOW,
            "updated_at": _NOW,
            # Forward-compat null fields
            "device_index": None,
            "is_loopback": None,
            "audio_template_id": None,
        },
    }
    _write_store(path, "audio_sources", sources)


# ── Scene Presets ──────────────────────────────────────────────────

def _seed_scene_presets(path: Path) -> None:
    presets = {
        _SCENE_ID: {
            "id": _SCENE_ID,
            "name": "Demo Ambient",
            "description": "Activates gradient on the strip and screen capture on the matrix",
            "tags": ["demo"],
            "order": 0,
            "targets": [
                {
                    "target_id": _TARGET_IDS["strip"],
                    "running": True,
                    "color_strip_source_id": _CSS_IDS["gradient"],
                    "brightness_value_source_id": "",
                    "fps": 30,
                },
                {
                    "target_id": _TARGET_IDS["matrix"],
                    "running": True,
                    "color_strip_source_id": _CSS_IDS["picture"],
                    "brightness_value_source_id": "",
                    "fps": 30,
                },
            ],
            "created_at": _NOW,
            "updated_at": _NOW,
        },
    }
    _write_store(path, "scene_presets", presets)
