//! Catalog seed data — run via `cargo loco seed`.

use loco_rs::prelude::*;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};

use crate::{
    models::_entities::{categories, product_variants, products},
    shared::slug::slugify,
};

// -- Categories -----------------------------------------------------------

struct CategorySeed {
    name: &'static str,
    description: &'static str,
    position: i32,
}

const CATEGORIES: &[CategorySeed] = &[
    CategorySeed {
        name: "Electronics",
        description: "Audio, computing, and smart devices",
        position: 0,
    },
    CategorySeed {
        name: "Accessories",
        description: "Cables, adapters, cases, and everyday essentials",
        position: 1,
    },
    CategorySeed {
        name: "Home & Office",
        description: "Ergonomic furniture, lighting, and desk organization",
        position: 2,
    },
];

// -- Products -------------------------------------------------------------

struct ProductSeed {
    name: &'static str,
    description: &'static str,
    price_cents: i64,
    stock: i32,
    category_slug: &'static str,
    sku: Option<&'static str>,
}

const PRODUCTS: &[ProductSeed] = &[
    ProductSeed {
        name: "Wireless Headphones",
        description: "Over-ear Bluetooth headphones with active noise cancelling, 30-hour battery life, and plush memory-foam cushions.",
        price_cents: 7_999,
        stock: 25,
        category_slug: "electronics",
        sku: Some("WH-1000"),
    },
    ProductSeed {
        name: "Mechanical Keyboard",
        description: "Tenkeyless mechanical keyboard with hot-swappable switches, per-key RGB backlight, and a detachable USB-C cable.",
        price_cents: 12_999,
        stock: 15,
        category_slug: "electronics",
        sku: Some("MK-TKL-RGB"),
    },
    ProductSeed {
        name: "USB-C Hub",
        description: "7-in-1 USB-C hub with HDMI 4K output, 100 W power delivery pass-through, SD card reader, and three USB-A 3.2 ports.",
        price_cents: 3_499,
        stock: 40,
        category_slug: "accessories",
        sku: Some("USBC-HUB7"),
    },
    ProductSeed {
        name: "Laptop Stand",
        description: "Adjustable aluminium laptop stand with ventilated surface. Supports laptops from 10\u{201d} to 17\u{201d}.",
        price_cents: 4_999,
        stock: 30,
        category_slug: "accessories",
        sku: Some("LS-ALU-01"),
    },
    ProductSeed {
        name: "Desk Lamp",
        description: "LED desk lamp with 5 colour temperatures, stepless brightness control, and a flexible gooseneck arm.",
        price_cents: 3_999,
        stock: 20,
        category_slug: "home-office",
        sku: Some("DL-5CT"),
    },
    ProductSeed {
        name: "Ergonomic Mouse",
        description: "Vertical wireless ergonomic mouse with 6 buttons, adjustable DPI up to 4 000, and a sculpted thumb rest.",
        price_cents: 5_999,
        stock: 18,
        category_slug: "electronics",
        sku: Some("EM-VW-01"),
    },
    ProductSeed {
        name: "Webcam Privacy Cover",
        description: "Ultra-thin sliding webcam cover compatible with laptops, tablets, and external monitors. Pack of 3.",
        price_cents: 599,
        stock: 100,
        category_slug: "accessories",
        sku: Some("WPC-3PK"),
    },
    ProductSeed {
        name: "Cable Organizer Set",
        description: "Silicone cable management kit with 6 magnetic clips, 4 velcro straps, and an under-desk cable tray.",
        price_cents: 1_299,
        stock: 50,
        category_slug: "home-office",
        sku: Some("COS-MAG"),
    },
];

// -- Public API -----------------------------------------------------------

/// Insert starter categories and products. Called from the `seed()` hook.
pub async fn seed_catalog(ctx: &AppContext) -> Result<()> {
    for cat in CATEGORIES {
        let slug = slugify(cat.name);
        let exists = categories::Entity::find()
            .filter(categories::Column::Slug.eq(&slug))
            .one(&ctx.db)
            .await?
            .is_some();
        if exists {
            continue;
        }
        categories::ActiveModel {
            name: Set(cat.name.to_string()),
            slug: Set(slug),
            description: Set(Some(cat.description.to_string())),
            position: Set(cat.position),
            published: Set(true),
            ..Default::default()
        }
        .insert(&ctx.db)
        .await?;
    }

    for item in PRODUCTS {
        let product_slug = slugify(item.name);
        let exists = products::Entity::find()
            .filter(products::Column::Slug.eq(&product_slug))
            .one(&ctx.db)
            .await?
            .is_some();
        if exists {
            continue;
        }

        let cat_slug = slugify(item.category_slug);
        let category = categories::Entity::find()
            .filter(categories::Column::Slug.eq(&cat_slug))
            .one(&ctx.db)
            .await?;

        let now = chrono::Utc::now();

        let product = products::ActiveModel {
            name: Set(item.name.to_string()),
            slug: Set(product_slug),
            description: Set(Some(item.description.to_string())),
            published: Set(true),
            published_at: Set(Some(now.into())),
            category_id: Set(category.map(|c| c.id)),
            ..Default::default()
        }
        .insert(&ctx.db)
        .await?;

        // Each seed product ships as a single default (unlabelled) variant
        // carrying its price/stock/sku.
        product_variants::ActiveModel {
            product_id: Set(product.id),
            label: Set(String::new()),
            position: Set(0),
            sku: Set(item.sku.map(|s| s.to_string())),
            stock: Set(Some(item.stock)),
            price_cents: Set(item.price_cents),
            ..Default::default()
        }
        .insert(&ctx.db)
        .await?;
    }

    Ok(())
}
