-- Agrarian terrain tile registry prototype.
-- This schema is intentionally separate from player/world persistence so
-- terrain packages can be regenerated without overwriting player history.

CREATE TABLE IF NOT EXISTS terrain_tiles (
    tile_id TEXT PRIMARY KEY,
    display_name TEXT NOT NULL,
    grid_scheme TEXT NOT NULL,
    projection TEXT NOT NULL,
    utm_zone TEXT,
    easting_min_m INTEGER NOT NULL,
    northing_min_m INTEGER NOT NULL,
    easting_max_m INTEGER NOT NULL,
    northing_max_m INTEGER NOT NULL,
    tile_size_m INTEGER NOT NULL CHECK (tile_size_m = 1000),
    center_latitude REAL NOT NULL CHECK (center_latitude >= -90 AND center_latitude <= 90),
    center_longitude REAL NOT NULL CHECK (center_longitude >= -180 AND center_longitude <= 180),
    status TEXT NOT NULL CHECK (status IN (
        'unknown',
        'queued',
        'source_data_found',
        'generated',
        'validated',
        'packaged',
        'published',
        'deprecated',
        'blocked'
    )),
    biome_primary TEXT NOT NULL DEFAULT 'unknown',
    generation_version INTEGER NOT NULL DEFAULT 0,
    package_version INTEGER NOT NULL DEFAULT 0,
    notes TEXT NOT NULL DEFAULT '',
    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_terrain_tiles_grid
ON terrain_tiles (grid_scheme, projection, utm_zone, easting_min_m, northing_min_m);

CREATE INDEX IF NOT EXISTS idx_terrain_tiles_status
ON terrain_tiles (status);

CREATE TABLE IF NOT EXISTS terrain_tile_solar_metadata (
    tile_id TEXT PRIMARY KEY,
    time_zone_id TEXT NOT NULL,
    standard_utc_offset_hours REAL NOT NULL CHECK (standard_utc_offset_hours >= -12 AND standard_utc_offset_hours <= 14),
    daylight_utc_offset_hours REAL NOT NULL CHECK (daylight_utc_offset_hours >= -12 AND daylight_utc_offset_hours <= 14),
    solar_model TEXT NOT NULL DEFAULT 'NOAA approximate sunrise/sunset',
    generated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE TABLE IF NOT EXISTS terrain_tile_growing_season_metadata (
    tile_id TEXT PRIMARY KEY,
    growing_zone_label TEXT NOT NULL,
    climate_profile TEXT NOT NULL DEFAULT 'unknown',
    growing_season_start_day INTEGER NOT NULL CHECK (growing_season_start_day >= 1 AND growing_season_start_day <= 366),
    growing_season_end_day INTEGER NOT NULL CHECK (growing_season_end_day >= 1 AND growing_season_end_day <= 366),
    frost_free_days INTEGER NOT NULL CHECK (frost_free_days >= 0 AND frost_free_days <= 366),
    min_average_growing_temp_c REAL NOT NULL DEFAULT 7.0,
    crop_safety_buffer_days INTEGER NOT NULL DEFAULT 14 CHECK (crop_safety_buffer_days >= 0 AND crop_safety_buffer_days <= 90),
    data_basis TEXT NOT NULL DEFAULT '',
    generated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE TABLE IF NOT EXISTS terrain_tile_weather_lookup_metadata (
    tile_id TEXT PRIMARY KEY,
    lookup_latitude REAL NOT NULL CHECK (lookup_latitude >= -90 AND lookup_latitude <= 90),
    lookup_longitude REAL NOT NULL CHECK (lookup_longitude >= -180 AND lookup_longitude <= 180),
    coordinate_source TEXT NOT NULL CHECK (coordinate_source IN ('tile_center', 'manual_override', 'provider_grid_point')),
    primary_provider TEXT NOT NULL DEFAULT 'open-meteo',
    fallback_provider TEXT NOT NULL DEFAULT '',
    fallback_provider_eligible INTEGER NOT NULL DEFAULT 0 CHECK (fallback_provider_eligible IN (0, 1)),
    lookup_rule TEXT NOT NULL DEFAULT '',
    generated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE TABLE IF NOT EXISTS terrain_tile_neighbors (
    tile_id TEXT NOT NULL,
    direction TEXT NOT NULL CHECK (direction IN ('n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw')),
    neighbor_tile_id TEXT NOT NULL,
    PRIMARY KEY (tile_id, direction),
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id),
    FOREIGN KEY (neighbor_tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE TABLE IF NOT EXISTS terrain_tile_sources (
    tile_source_id INTEGER PRIMARY KEY AUTOINCREMENT,
    tile_id TEXT NOT NULL,
    source_kind TEXT NOT NULL,
    source_name TEXT NOT NULL,
    source_uri TEXT NOT NULL DEFAULT '',
    license_name TEXT NOT NULL DEFAULT '',
    source_version TEXT NOT NULL DEFAULT '',
    coverage_status TEXT NOT NULL CHECK (coverage_status IN (
        'needed',
        'candidate',
        'confirmed',
        'missing',
        'not_applicable'
    )),
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE INDEX IF NOT EXISTS idx_terrain_tile_sources_tile
ON terrain_tile_sources (tile_id, source_kind);

CREATE TABLE IF NOT EXISTS terrain_tile_packages (
    package_id TEXT PRIMARY KEY,
    tile_id TEXT NOT NULL,
    package_version INTEGER NOT NULL,
    unreal_engine_version TEXT NOT NULL,
    world_partition_ready INTEGER NOT NULL DEFAULT 0 CHECK (world_partition_ready IN (0, 1)),
    package_uri TEXT NOT NULL DEFAULT '',
    content_hash TEXT NOT NULL DEFAULT '',
    package_size_bytes INTEGER NOT NULL DEFAULT 0,
    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    published_at TEXT,
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE INDEX IF NOT EXISTS idx_terrain_tile_packages_tile
ON terrain_tile_packages (tile_id, package_version);

CREATE TABLE IF NOT EXISTS terrain_tile_generation_jobs (
    job_id TEXT PRIMARY KEY,
    tile_id TEXT NOT NULL,
    job_type TEXT NOT NULL,
    status TEXT NOT NULL CHECK (status IN (
        'queued',
        'running',
        'succeeded',
        'failed',
        'cancelled'
    )),
    requested_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    started_at TEXT,
    finished_at TEXT,
    log_uri TEXT NOT NULL DEFAULT '',
    error_summary TEXT NOT NULL DEFAULT '',
    FOREIGN KEY (tile_id) REFERENCES terrain_tiles(tile_id)
);

CREATE INDEX IF NOT EXISTS idx_terrain_tile_generation_jobs_tile
ON terrain_tile_generation_jobs (tile_id, status);
