//! Per-customer shipping/contact profile: the address + phone fields used to
//! prefill checkout. One row per user (unique `user_id`); `name`/`email` are
//! read from `users`, never duplicated here.

pub use crate::models::_entities::customer_profiles::{ActiveModel, Column, Entity, Model};
use sea_orm::entity::prelude::*;
use sea_orm::{ActiveValue, IntoActiveModel, QueryFilter, TryIntoModel};

pub type CustomerProfiles = Entity;

/// The editable profile fields, shared by the profile page and the checkout
/// "save my address" path. The `company_*` fields are only meaningful for
/// company accounts (account type now lives on `users`, fixed at registration).
#[derive(Debug, Default, Clone)]
pub struct ProfileFields {
    pub company_name: Option<String>,
    pub company_id: Option<String>,
    pub tax_id: Option<String>,
    pub vat_id: Option<String>,
    pub phone_prefix: Option<String>,
    pub phone: Option<String>,
    pub address: Option<String>,
    pub city: Option<String>,
    pub zip: Option<String>,
    pub country: Option<String>,
}

#[async_trait::async_trait]
impl ActiveModelBehavior for ActiveModel {
    async fn before_save<C>(self, _db: &C, _insert: bool) -> std::result::Result<Self, DbErr>
    where
        C: ConnectionTrait,
    {
        Ok(self)
    }
}

impl Model {
    /// The profile for `user_id`, if one exists.
    pub async fn find_for_user(db: &DatabaseConnection, user_id: i32) -> Result<Option<Self>, DbErr> {
        Entity::find()
            .filter(Column::UserId.eq(user_id))
            .one(db)
            .await
    }

    /// Insert or update the profile for `user_id` with `fields`, returning the
    /// persisted row. The unique `user_id` index keeps this 1:1.
    pub async fn upsert(
        db: &DatabaseConnection,
        user_id: i32,
        fields: ProfileFields,
    ) -> Result<Self, DbErr> {
        let mut active = match Self::find_for_user(db, user_id).await? {
            Some(existing) => existing.into_active_model(),
            None => ActiveModel {
                user_id: ActiveValue::set(user_id),
                ..Default::default()
            },
        };
        active.company_name = ActiveValue::set(fields.company_name);
        active.company_id = ActiveValue::set(fields.company_id);
        active.tax_id = ActiveValue::set(fields.tax_id);
        active.vat_id = ActiveValue::set(fields.vat_id);
        active.phone_prefix = ActiveValue::set(fields.phone_prefix);
        active.phone = ActiveValue::set(fields.phone);
        active.address = ActiveValue::set(fields.address);
        active.city = ActiveValue::set(fields.city);
        active.zip = ActiveValue::set(fields.zip);
        active.country = ActiveValue::set(fields.country);
        active.save(db).await?.try_into_model()
    }
}
