package main

import (
	"encoding/json"
	"net/http"
	"os"
	"sort"
	"strings"
)

type treeEntry struct {
	Name string `json:"name"`
	Kind string `json:"kind"`
}

type treeResponse struct {
	Path    string      `json:"path"`
	Entries []treeEntry `json:"entries"`
}

// handleTree responds with a JSON listing of the immediate children of the
// folder at fsPath. Hidden entries and `index.md` are filtered. Files are not
// descended — the client lazy-loads children on expand.
func (h *handler) handleTree(w http.ResponseWriter, r *http.Request, urlPath, fsPath string) {
	info, err := os.Stat(fsPath)
	if err != nil {
		if os.IsNotExist(err) {
			http.NotFound(w, r)
			return
		}
		http.Error(w, "stat failed", http.StatusInternalServerError)
		return
	}
	if !info.IsDir() {
		http.Error(w, "not a folder", http.StatusBadRequest)
		return
	}

	entries, err := listTreeEntries(fsPath)
	if err != nil {
		http.Error(w, "read failed", http.StatusInternalServerError)
		return
	}

	resp := treeResponse{Path: canonicalTreePath(urlPath), Entries: entries}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	_ = json.NewEncoder(w).Encode(resp)
}

// canonicalTreePath returns the URL path in the form used by the picker:
// "/" for root, otherwise stripped of any trailing slash.
func canonicalTreePath(urlPath string) string {
	if urlPath == "" || urlPath == "/" {
		return "/"
	}
	return "/" + strings.Trim(urlPath, "/")
}

// listTreeEntries returns the immediate children of fsPath, filtering hidden
// entries and index.md. Folders are listed before files; both groups are
// sorted alphabetically.
func listTreeEntries(fsPath string) ([]treeEntry, error) {
	raw, err := os.ReadDir(fsPath)
	if err != nil {
		return nil, err
	}
	var folders, files []treeEntry
	for _, e := range raw {
		name := e.Name()
		if strings.HasPrefix(name, ".") {
			continue
		}
		if e.IsDir() {
			folders = append(folders, treeEntry{Name: name, Kind: "folder"})
		} else {
			if name == "index.md" {
				continue
			}
			files = append(files, treeEntry{Name: name, Kind: "file"})
		}
	}
	sort.Slice(folders, func(i, j int) bool { return folders[i].Name < folders[j].Name })
	sort.Slice(files, func(i, j int) bool { return files[i].Name < files[j].Name })
	return append(folders, files...), nil
}
