package main

import (
	"embed"
	"html/template"
	"io"
	"io/fs"
	"net/http"
	"os"
	"regexp"
	"strings"

	"github.com/justinas/nosurf"
)

//go:embed templates/*.html static/*
var content embed.FS

type TemplateData struct {
	CSRFToken     string
	PageData      interface{}
	Authenticated bool
	AppName       string
}

func renderTemplate(w http.ResponseWriter, r *http.Request, tmpl string, pageData interface{}) {
	// Check if user is authenticated
	session, _ := store.Get(r, "session")
	isAuth := false
	if auth, ok := session.Values["authenticated"].(bool); ok {
		isAuth = auth
	}

	configMu.RLock()
	appName := config.AppName
	configMu.RUnlock()

	td := TemplateData{
		CSRFToken:     nosurf.Token(r),
		PageData:      pageData,
		Authenticated: isAuth,
		AppName:       appName,
	}

	templatesFS, _ := fs.Sub(content, "templates")
	// Parse base.html and the specific page template together
	files := []string{"base.html", tmpl}
	t, err := template.ParseFS(templatesFS, files...)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// Execute base.html which contains {{ block "content" . }}
	// The specific page template's {{ define "content" }} will override the block
	err = t.ExecuteTemplate(w, "base.html", td)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func copyFile(src, dst string) error {
	source, err := os.Open(src)
	if err != nil {
		return err
	}
	defer source.Close()

	destination, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer destination.Close()

	_, err = io.Copy(destination, source)
	return err
}

func readLines(file string) ([]string, error) {
	data, err := os.ReadFile(file)
	if err != nil {
		return nil, err
	}
	lines := strings.Split(string(data), "\n")
	var cleaned []string
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line != "" {
			cleaned = append(cleaned, line)
		}
	}
	return cleaned, nil
}

func writeLines(file string, lines []string) {
	data := strings.Join(lines, "\n")
	os.WriteFile(file, []byte(data), 0644)
}

func mergeUnique(data1, data2 string) string {
	lines1 := strings.Split(data1, "\n")
	lines2 := strings.Split(data2, "\n")
	all := append(lines1, lines2...)

	// Sort for consistency
	var sorted []string
	seen := make(map[string]bool)
	for _, line := range all {
		line = strings.TrimSpace(line)
		if line == "" || seen[line] {
			continue
		}
		sorted = append(sorted, line)
		seen[line] = true
	}

	// Sort alphabetically
	for i := 0; i < len(sorted); i++ {
		for j := i + 1; j < len(sorted); j++ {
			if sorted[i] > sorted[j] {
				sorted[i], sorted[j] = sorted[j], sorted[i]
			}
		}
	}

	return strings.Join(sorted, "\n")
}

func sanitizeInput(input string) string {
	// Basic sanitization, remove dangerous chars
	re := regexp.MustCompile(`[;<>&|]`)
	return re.ReplaceAllString(input, "")
}

func isValidURL(u string) bool {
	return strings.HasPrefix(u, "http://") || strings.HasPrefix(u, "https://")
}

func isValidDomain(d string) bool {
	re := regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9.-]*\.[a-zA-Z]{2,}$`)
	return re.MatchString(d)
}

func generateSecret() string {
	// This function is kept for backward compatibility but is not currently used
	// since we're using pquerna/otp for TOTP generation
	return ""
}
