{{!-- Template for Direct Roman → Devanagari converters with precomputed mappings --}}

/// Optimized {{original_script}} to Devanagari converter with precomputed direct mappings
/// This converter uses compile-time composition of {{original_script}} → ISO-15919 → Devanagari
/// to eliminate runtime hub conversion overhead
#[allow(dead_code)]
pub struct {{struct_name}} {
    {{lowercase original_script}}_to_deva_map: FxHashMap<String, &'static str>,
}

impl {{struct_name}} {
    pub fn new() -> Self {
        let mut {{lowercase original_script}}_to_deva = FxHashMap::default();
        
        // Direct {{original_script}} → Devanagari mappings (precomputed at compile time)
{{#each mappings}}
        {{lowercase ../original_script}}_to_deva.insert("{{@key}}".to_string(), "{{this}}");
{{/each}}
        
        Self {
            {{lowercase original_script}}_to_deva_map: {{lowercase original_script}}_to_deva,
        }
    }
    
    /// Convert {{original_script}} directly to Devanagari using precomputed mappings
    /// This implements the same logic as the hub's ISO → Devanagari conversion
    pub fn {{lowercase original_script}}_to_devanagari(&self, input: &str) -> Result<String, ConverterError> {
        let mut result = String::with_capacity(input.len() * 2);
        let chars: Vec<char> = input.chars().collect();
        let mut i = 0;

        while i < chars.len() {
            let ch = chars[i];

            if ch.is_whitespace() {
                result.push(ch);
                i += 1;
                continue;
            }

            // Handle ASCII punctuation except for characters that might be in our mapping
            if ch.is_ascii_punctuation() && ch != '\'' {
                result.push(ch);
                i += 1;
                continue;
            }

            let mut parsed = false;

            // Try to find consonant + vowel combinations (same logic as hub)
            for total_len in (2..=4).rev() {
                if i + total_len > chars.len() {
                    continue;
                }

                // Try different consonant lengths within this total
                for cons_len in 1..total_len {
                    let vowel_len = total_len - cons_len;
                    if vowel_len > 3 {
                        continue;
                    }

                    let cons_seq: String = chars[i..i + cons_len].iter().collect();
                    let cons_with_a = format!("{}a", cons_seq);

                    // Check if this consonant exists in our mappings (with inherent 'a')
                    if let Some(&cons_char) = self.{{lowercase original_script}}_to_deva_map.get(&cons_with_a) {
                        // Found a consonant, check the vowel part
                        let vowel_seq: String = chars[i + cons_len..i + total_len].iter().collect();

                        // Check if this vowel exists in our mapping
                        if self.{{lowercase original_script}}_to_deva_map.contains_key(&vowel_seq) {
                            if vowel_seq == "a" {
                                // Inherent vowel - just output the consonant
                                result.push_str(cons_char);
                                i += total_len;
                                parsed = true;
                                break;
                            } else {
                                // Get vowel sign mapping
                                let vowel_sign_key = format!("__vowel_sign_{}", vowel_seq);
                                if let Some(&sign) = self.{{lowercase original_script}}_to_deva_map.get(&vowel_sign_key) {
                                    // Consonant + vowel sign
                                    result.push_str(cons_char);
                                    result.push_str(sign);
                                    i += total_len;
                                    parsed = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if parsed {
                    break;
                }
            }

            // If no consonant+vowel found, try bare consonant
            if !parsed {
                for cons_len in (1..=3).rev() {
                    if i + cons_len > chars.len() {
                        continue;
                    }

                    let cons_seq: String = chars[i..i + cons_len].iter().collect();
                    let cons_with_a = format!("{}a", cons_seq);

                    if let Some(&cons_char) = self.{{lowercase original_script}}_to_deva_map.get(&cons_with_a) {
                        // No vowel found, treat as bare consonant
                        result.push_str(cons_char);
                        result.push('्'); // virama
                        i += cons_len;
                        parsed = true;
                        break;
                    }
                }
            }

            // If consonant+vowel parsing failed, try direct matches (for vowels, marks, etc.)
            if !parsed {
                let mut best_match: Option<(&str, usize)> = None;

                // Try sequences of decreasing length
                for len in (1..=4).rev() {
                    if i + len > chars.len() {
                        continue;
                    }

                    let seq: String = chars[i..i + len].iter().collect();
                    if let Some(&deva_str) = self.{{lowercase original_script}}_to_deva_map.get(&seq) {
                        best_match = Some((deva_str, len));
                        break;
                    }
                }

                if let Some((matched_str, len)) = best_match {
                    // Check if this is a consonant that needs virama
                    let matched_chars: Vec<char> = matched_str.chars().collect();
                    let is_consonant = if matched_chars.len() >= 1 {
                        let first_char_code = matched_chars[0] as u32;
                        // Check if first character is a Devanagari consonant
                        (first_char_code >= 0x0915 && first_char_code <= 0x0939) || // Basic consonants
                        (first_char_code >= 0x0958 && first_char_code <= 0x095F) || // Precomposed nukta consonants
                        (first_char_code == 0x0933 || first_char_code == 0x0934 || first_char_code == 0x0935) // Additional
                    } else {
                        false
                    };
                    
                    if is_consonant {
                        // Check if next char is NOT a vowel (needs virama)
                        let needs_virama = if i + len < chars.len() {
                            let next_chars: String = chars[i + len..].iter().take(3).collect();
                            // Check if any vowel follows
                            !["a", "ā", "i", "ī", "u", "ū", "e", "ai", "o", "au", "r̥", "r̥̄", "l̥", "l̥̄"]
                                .iter()
                                .any(|v| next_chars.starts_with(v))
                        } else {
                            true // End of string
                        };
                        
                        result.push_str(matched_str);
                        if needs_virama {
                            result.push('्'); // virama
                        }
                    } else {
                        // Not a consonant (vowel, mark, etc.) - just add as-is
                        result.push_str(matched_str);
                    }
                    
                    i += len;
                    parsed = true;
                }
            }

            if !parsed {
                // Unknown character - pass through gracefully
                result.push(ch);
                i += 1;
            }
        }

        Ok(result)
    }
    
    /// Convert Devanagari to {{original_script}} (reverse conversion via standard path)
    pub fn devanagari_to_{{lowercase original_script}}(&self, input: &str) -> Result<String, ConverterError> {
        // For reverse conversion, use the existing hub-based path
        // This is acceptable since Roman → Indic is the performance bottleneck, not Indic → Roman
        let {{lowercase original_script}}_converter = {{capitalize original_script}}Converter::new();
        let hub = crate::modules::hub::Hub::new();
        
        // Devanagari → ISO-15919 → {{original_script}}
        use crate::modules::hub::HubTrait;
        let iso_result = hub.deva_to_iso(input)
            .map_err(|e| ConverterError::ConversionFailed {
                script: "{{original_script}}".to_string(),
                reason: format!("Hub conversion failed: {}", e),
            })?;
        
        match iso_result {
            HubFormat::Iso(iso_text) => {
                let result = {{lowercase original_script}}_converter.from_hub("{{original_script}}", &HubInput::Iso(iso_text))?;
                Ok(result)
            },
            _ => Err(ConverterError::ConversionFailed {
                script: "{{original_script}}".to_string(),
                reason: "Expected ISO output from hub".to_string(),
            }),
        }
    }
}

impl ScriptConverter for {{struct_name}} {
    fn to_hub(&self, script: &str, input: &str) -> Result<HubInput, ConverterError> {
        if script != "{{script_name}}" {
            return Err(ConverterError::InvalidInput {
                script: script.to_string(),
                message: "{{struct_name}} converter only supports '{{script_name}}' script".to_string(),
            });
        }
        
        let deva_text = self.{{lowercase original_script}}_to_devanagari(input)?;
        Ok(HubInput::Devanagari(deva_text))
    }
    
    fn from_hub(&self, script: &str, hub_input: &HubInput) -> Result<String, ConverterError> {
        if script != "{{script_name}}" {
            return Err(ConverterError::InvalidInput {
                script: script.to_string(),
                message: "{{struct_name}} converter only supports '{{script_name}}' script".to_string(),
            });
        }
        
        match hub_input {
            HubInput::Devanagari(deva_text) => self.devanagari_to_{{lowercase original_script}}(deva_text),
            HubInput::Iso(_) => Err(ConverterError::ConversionFailed {
                script: script.to_string(),
                reason: "{{struct_name}} converter expects Devanagari input, got ISO".to_string(),
            }),
        }
    }
    
    fn supported_scripts(&self) -> Vec<&'static str> {
        vec!["{{script_name}}"]
    }
    
    fn script_has_implicit_a(&self, _script: &str) -> bool {
        {{has_implicit_a}}
    }
}

impl Default for {{struct_name}} {
    fn default() -> Self {
        Self::new()
    }
}