-- =============================================================================
-- 洗车记录系统 - Migration 0001: 基础表（Node.js / better-sqlite3 版）
-- =============================================================================

-- 基础 PRAGMA 由 server/src/db.js 统一设置（journal_mode=WAL / foreign_keys=ON / synchronous=NORMAL / busy_timeout=5000）

-- -----------------------------------------------------------------------------
-- 1. chemicals - 药剂字典（Grocy 缓存层）
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS chemicals (
    grocy_product_id  TEXT    NOT NULL,
    name              TEXT    NOT NULL,
    category          TEXT,
    unit              TEXT    NOT NULL DEFAULT 'ml',
    standard_dose     REAL,
    notes             TEXT,
    is_active         INTEGER NOT NULL DEFAULT 1 CHECK (is_active IN (0, 1)),
    fetched_at        TEXT,
    created_at        TEXT    NOT NULL DEFAULT (datetime('now')),
    updated_at        TEXT    NOT NULL DEFAULT (datetime('now')),
    PRIMARY KEY (grocy_product_id)
);

CREATE INDEX IF NOT EXISTS idx_chemicals_category ON chemicals(category);
CREATE INDEX IF NOT EXISTS idx_chemicals_active   ON chemicals(is_active);
CREATE INDEX IF NOT EXISTS idx_chemicals_fetched  ON chemicals(fetched_at);

-- -----------------------------------------------------------------------------
-- 2. weather_snapshots - 天气快照
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS weather_snapshots (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    snapshot_date   TEXT    NOT NULL,
    city            TEXT    NOT NULL,
    provider        TEXT    NOT NULL CHECK (provider IN ('qweather','openweathermap')),
    temp_c          REAL,
    humidity        INTEGER,
    weather_desc    TEXT,
    weather_code    TEXT,
    wind_kph        REAL,
    precip_mm       REAL,
    raw_json        TEXT,
    fetched_at      TEXT    NOT NULL DEFAULT (datetime('now'))
);

CREATE UNIQUE INDEX IF NOT EXISTS uk_weather_city_date ON weather_snapshots(city, snapshot_date);
CREATE INDEX IF NOT EXISTS idx_weather_date ON weather_snapshots(snapshot_date);

-- -----------------------------------------------------------------------------
-- 3. wash_records - 洗车记录
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS wash_records (
    id                  INTEGER PRIMARY KEY AUTOINCREMENT,
    wash_date           TEXT    NOT NULL,
    wash_type           TEXT    NOT NULL CHECK (wash_type IN ('quick','full','detail','other')),
    weather_snapshot_id INTEGER,
    location            TEXT,
    cost                REAL    NOT NULL DEFAULT 0,
    duration_min        INTEGER,
    notes               TEXT,
    created_at          TEXT    NOT NULL DEFAULT (datetime('now')),
    updated_at          TEXT    NOT NULL DEFAULT (datetime('now')),
    FOREIGN KEY (weather_snapshot_id) REFERENCES weather_snapshots(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS idx_wash_records_date ON wash_records(wash_date);
CREATE INDEX IF NOT EXISTS idx_wash_records_type ON wash_records(wash_type);
CREATE INDEX IF NOT EXISTS idx_wash_records_weather ON wash_records(weather_snapshot_id);

-- -----------------------------------------------------------------------------
-- 4. chemical_usage - 药剂消耗
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS chemical_usage (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    usage_date      TEXT    NOT NULL,
    chemical_id     TEXT    NOT NULL,
    amount          REAL    NOT NULL,
    wash_record_id  INTEGER,
    notes           TEXT,
    sync_status     TEXT    NOT NULL DEFAULT 'pending' CHECK (sync_status IN ('pending','synced','failed')),
    sync_at         TEXT,
    created_at      TEXT    NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT    NOT NULL DEFAULT (datetime('now')),
    FOREIGN KEY (chemical_id)    REFERENCES chemicals(grocy_product_id) ON DELETE RESTRICT,
    FOREIGN KEY (wash_record_id) REFERENCES wash_records(id)        ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS idx_usage_date     ON chemical_usage(usage_date);
CREATE INDEX IF NOT EXISTS idx_usage_chemical ON chemical_usage(chemical_id);
CREATE INDEX IF NOT EXISTS idx_usage_wash     ON chemical_usage(wash_record_id);
CREATE INDEX IF NOT EXISTS idx_usage_sync     ON chemical_usage(sync_status);

-- -----------------------------------------------------------------------------
-- 5. settings - 运行时配置 KV
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS settings (
    key         TEXT    NOT NULL PRIMARY KEY,
    value       TEXT,
    is_secret   INTEGER NOT NULL DEFAULT 0,
    description TEXT,
    updated_at  TEXT    NOT NULL DEFAULT (datetime('now'))
);

-- 预置 11 个 key
INSERT OR IGNORE INTO settings (key, value, is_secret, description) VALUES
    ('db_path',                NULL, 0, '数据库路径（SQLite 模式）'),
    ('app_city',               NULL, 0, '所在城市（用于天气查询）'),
    ('app_timezone',           'Asia/Shanghai', 0, 'PHP 时区（保留兼容）'),
    ('grocy_url',              NULL, 0, 'Grocy 实例 URL'),
    ('grocy_api_token',        NULL, 1, 'Grocy REST API token'),
    ('weather_provider',       'qweather', 0, '天气提供方 qweather/openweathermap'),
    ('qweather_api_key',       NULL, 1, '和风天气 API key'),
    ('qweather_api_host',      'api.qweather.com', 0, '和风 API host'),
    ('openweathermap_api_key', NULL, 1, 'OpenWeatherMap API key'),
    ('backup_keep_count',      '10', 0, '本地备份保留份数'),
    ('backup_dir',             'storage/backups', 0, '备份输出目录');

-- -----------------------------------------------------------------------------
-- 6. 视图
-- -----------------------------------------------------------------------------

DROP VIEW IF EXISTS v_wash_monthly_count;
CREATE VIEW v_wash_monthly_count AS
SELECT
    substr(wash_date, 1, 7) AS month,
    COUNT(*)                AS wash_count,
    SUM(COALESCE(cost, 0))  AS total_cost
FROM wash_records
GROUP BY substr(wash_date, 1, 7)
ORDER BY month DESC;

DROP VIEW IF EXISTS v_chemical_monthly_usage;
CREATE VIEW v_chemical_monthly_usage AS
SELECT
    substr(cu.usage_date, 1, 7) AS month,
    c.grocy_product_id          AS grocy_product_id,
    c.name                      AS chemical_name,
    c.unit                      AS unit,
    SUM(cu.amount)              AS total_amount,
    COUNT(*)                    AS usage_count
FROM chemical_usage cu
JOIN chemicals c ON c.grocy_product_id = cu.chemical_id
GROUP BY substr(cu.usage_date, 1, 7), c.grocy_product_id
ORDER BY month DESC, total_amount DESC;

DROP VIEW IF EXISTS v_last_wash;
CREATE VIEW v_last_wash AS
SELECT
    id              AS wash_id,
    wash_date,
    wash_type,
    CAST(julianday('now') - julianday(wash_date) AS INTEGER) AS days_since
FROM wash_records
ORDER BY wash_date DESC, id DESC
LIMIT 1;
