package handlers

import (
	"fmt"
	"strings"
)

func reservedFlowCode(value string) bool {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case "0", "kembali", "back", "keluar", "batal", "exit":
		return true
	default:
		return false
	}
}

// Saved drafts must be a navigable tree. Existing legacy structures can still
// be read by the runtime's basic validator while the operator repairs them.
func validateFlowForEditing(s flowStructure) error {
	if err := validateFlowStructure(s); err != nil {
		return err
	}
	parents := map[string]int{}
	for id, node := range s.Nodes {
		if len([]rune(id)) > 64 {
			return fmt.Errorf("ID menu terlalu panjang")
		}
		labels := map[string]bool{}
		for _, option := range node.Options {
			if reservedFlowCode(option.Key) {
				return fmt.Errorf("kode %q digunakan untuk kembali atau menutup menu; gunakan kode lain", option.Key)
			}
			label := strings.ToLower(strings.TrimSpace(option.Label))
			if label == "" {
				return fmt.Errorf("pilihan %q belum memiliki nama yang tampil di menu", option.Key)
			}
			if labels[label] {
				return fmt.Errorf("nama pilihan %q dipakai dua kali dalam menu yang sama", option.Label)
			}
			labels[label] = true
			if option.Action == "goto" {
				parents[option.Target]++
				if option.Target == s.Root || parents[option.Target] > 1 {
					return fmt.Errorf("submenu harus memiliki satu menu asal; gunakan perintah kembali untuk naik ke menu sebelumnya")
				}
			}
		}
	}
	seen, visiting := map[string]bool{}, map[string]bool{}
	var visit func(string) error
	visit = func(id string) error {
		if visiting[id] {
			return fmt.Errorf("alur memiliki putaran submenu yang tidak valid")
		}
		if seen[id] {
			return nil
		}
		seen[id], visiting[id] = true, true
		for _, option := range s.Nodes[id].Options {
			if option.Action == "goto" {
				if err := visit(option.Target); err != nil {
					return err
				}
			}
		}
		visiting[id] = false
		return nil
	}
	if err := visit(s.Root); err != nil {
		return err
	}
	if len(seen) != len(s.Nodes) {
		return fmt.Errorf("ada menu yang tidak terhubung ke menu utama; hubungkan atau hapus menu tersebut")
	}
	return nil
}

func validateFlowDisplay(mode string, s flowStructure) error {
	if mode != "auto" && mode != "text" && mode != "buttons" {
		return fmt.Errorf("mode tampilan menu tidak valid")
	}
	if mode == "buttons" {
		for _, node := range s.Nodes {
			if len(node.Options) > 0 && !flowNodeUsesButtons(mode, node) {
				return fmt.Errorf("mode tombol mendukung 1–3 pilihan per menu dengan nama maksimal 24 karakter")
			}
		}
	}
	return nil
}
