//! Controller for the `EmailWorker` CRD — Deployment only.

use crate::context::ReconcileState;
use crate::controller::app::{apply_deployment, patch_status};
use crate::controller::helpers::{child_meta, env_var_to_json, merge_env, owner_ref, query_deployment_status, std_labels};
use crate::crd::{EmailWorker, EmailWorkerSpec};
use serde_json::{Value, json};
use std::sync::Arc;

pub async fn reconcile(ew: Arc<EmailWorker>, ctx: Arc<ReconcileState>) -> Result<(), kube::Error> {
    let ns = ew.metadata.namespace.as_deref().unwrap_or("default");
    let name = ew.metadata.name.as_deref().unwrap_or("");
    let spec = &ew.spec;
    let client = &ctx.client;

    let or = owner_ref(&ew.metadata, &ew.api_version, &ew.kind);
    let labels = std_labels();

    let deployment = build_deployment(ns, name, spec, &or, &labels);
    apply_deployment(client, ns, name, &deployment).await?;

    let (ready_replicas, phase) = query_deployment_status(client, ns, name).await?;
    let status = json!({ "status": { "readyReplicas": ready_replicas, "phase": phase } });
    patch_status::<EmailWorker>(client, ns, name, &status).await?;

    Ok(())
}

fn build_deployment(
    ns: &str,
    name: &str,
    spec: &EmailWorkerSpec,
    or: &crate::crd::OwnerReference,
    labels: &std::collections::BTreeMap<String, String>,
) -> Value {
    let env = merge_env(&[], &spec.env);
    let image = if spec.image.is_empty() {
        "myapp/email-worker:latest".to_string()
    } else {
        spec.image.clone()
    };
    let pull = if spec.image_pull_policy.is_empty() {
        "IfNotPresent".to_string()
    } else {
        spec.image_pull_policy.clone()
    };
    let resources = super::app::build_resources(&spec.resources);

    json!({
        "metadata": child_meta(name, ns, or, labels.clone()),
        "spec": {
            "replicas": 1,
            "selector": { "matchLabels": labels },
            "template": {
                "metadata": { "labels": labels.clone() },
                "spec": {
                    "containers": [{
                        "name": "email-worker",
                        "image": image,
                        "env": env.iter().map(env_var_to_json).collect::<Vec<_>>(),
                        "imagePullPolicy": pull,
                        "resources": resources,
                    }]
                }
            }
        }
    })
}
