//! Ensures the built-in carrier delivery options (Packeta, DPD) always exist.
//!
//! These are the only delivery options the shop offers; the admin can price and
//! enable/disable them but cannot add or remove options. We insert each one
//! only when its `code` is missing, so an admin's price/enabled changes are
//! never overwritten on the next boot.

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

use crate::{models::shipping_methods, shared::shipping as shipping_rules};

/// `(code, name, carrier, requires_pickup_point, default_price_cents, position)`
const BUILTINS: [(&str, &str, &str, bool, i64, i32); 2] = [
    ("packeta", "Packeta", "packeta", true, 290, 0),
    ("dpd", "DPD", "dpd", false, 450, 1),
];

pub struct ShippingSeeder;

#[async_trait]
impl Initializer for ShippingSeeder {
    fn name(&self) -> String {
        "shipping-seeder".to_string()
    }

    async fn before_run(&self, ctx: &AppContext) -> Result<()> {
        for (code, name, carrier, requires_pickup_point, price_cents, position) in BUILTINS {
            let exists = shipping_methods::Entity::find()
                .filter(shipping_methods::Column::Code.eq(code))
                .count(&ctx.db)
                .await?
                > 0;
            if exists {
                continue;
            }
            shipping_methods::ActiveModel {
                code: Set(code.to_string()),
                name: Set(name.to_string()),
                carrier: Set(carrier.to_string()),
                requires_pickup_point: Set(requires_pickup_point),
                price_cents: Set(price_cents),
                enabled: Set(true),
                position: Set(position),
                ..Default::default()
            }
            .insert(&ctx.db)
            .await?;
            tracing::info!(carrier = code, "seeded built-in delivery option");
        }
        shipping_rules::disable_packeta_if_unconfigured(ctx).await
    }
}
