//! Svelte target — readable store per context, re-export per call.
//! Output shape lives at `templates/svelte/svelte.ts.j2`.

use std::path::PathBuf;

use askama::Template;

use crate::config::Config;
use crate::emit::CodegenTarget;
use crate::emit::EmittedFile;
use crate::emit::casing::pascal_case;
use crate::ir::{IsContext, MizanIR};


pub struct SvelteAdapter;


impl CodegenTarget for SvelteAdapter {
    fn name(&self) -> &'static str { "svelte" }

    fn emit(&self, ir: &MizanIR, _config: &Config) -> Vec<EmittedFile> {
        let content = build_template(ir).render().expect("svelte template renders");
        vec![EmittedFile::new(PathBuf::from("svelte.ts"), content)]
    }
}


#[derive(Template)]
#[template(path = "svelte/svelte.ts.j2", escape = "none")]
struct SvelteTemplate<'a> {
    stage1_imports: Vec<String>,
    contexts: Vec<CtxRender<'a>>,
    call_exports: Vec<String>,
}


struct CtxRender<'a> {
    pascal: String,
    name: &'a str,
    has_params: bool,
    params_arg: &'static str,
}


fn build_template(ir: &MizanIR) -> SvelteTemplate<'_> {
    let contexts: Vec<CtxRender> = ir.contexts.iter()
        .map(|(ctx_name, ctx_meta)| {
            let has_params = !ctx_meta.params.is_empty();
            CtxRender {
                pascal: pascal_case(ctx_name),
                name: ctx_name,
                has_params,
                params_arg: if has_params { "params" } else { "{} as any" },
            }
        })
        .collect();

    let mutations = ir.functions.iter()
        .filter(|f| matches!(f.is_context, IsContext::No) && !f.is_form && !f.affects.is_empty());
    let plain_fns = ir.functions.iter()
        .filter(|f| matches!(f.is_context, IsContext::No) && !f.is_form && f.affects.is_empty());
    let call_exports: Vec<String> = mutations.chain(plain_fns)
        .map(|f| pascal_case(&f.camel_name))
        .collect();

    let mut stage1: Vec<String> = Vec::new();
    for ctx_name in ir.contexts.keys() {
        let p = pascal_case(ctx_name);
        stage1.push(format!("fetch{p}Context"));
        stage1.push(format!("type {p}ContextData"));
        stage1.push(format!("type {p}ContextParams"));
    }
    for c in &call_exports {
        stage1.push(format!("call{c}"));
    }

    SvelteTemplate { stage1_imports: stage1, contexts, call_exports }
}
