package api

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"net/http"
)

// POST /api/v1/installer/upload?platform=freebsd — Installer-Paket hochladen (ZIP oder Script)
func (h *Handler) uploadInstaller(w http.ResponseWriter, r *http.Request) {
	platform := r.URL.Query().Get("platform")
	if platform == "" {
		platform = "freebsd"
	}
	validPlatforms := map[string]bool{"freebsd": true, "linux": true, "windows": true}
	if !validPlatforms[platform] {
		writeError(w, http.StatusBadRequest, "Ungueltige Plattform (freebsd, linux, windows)")
		return
	}

	// Max 50MB
	r.Body = http.MaxBytesReader(w, r.Body, 50*1024*1024)

	// Multipart oder raw body
	var data []byte
	var filename string
	var err error

	if ct := r.Header.Get("Content-Type"); ct != "" && len(ct) > 19 && ct[:19] == "multipart/form-data" {
		file, header, ferr := r.FormFile("file")
		if ferr != nil {
			writeError(w, http.StatusBadRequest, "Datei fehlt im Upload")
			return
		}
		defer file.Close()
		data, err = io.ReadAll(file)
		filename = header.Filename
	} else {
		data, err = io.ReadAll(r.Body)
		filename = r.URL.Query().Get("filename")
		if filename == "" {
			filename = fmt.Sprintf("installer-%s.zip", platform)
		}
	}

	if err != nil || len(data) == 0 {
		writeError(w, http.StatusBadRequest, "Leere oder fehlerhafte Datei")
		return
	}

	hash := sha256.Sum256(data)
	hashStr := hex.EncodeToString(hash[:])

	if err := h.db.SaveInstaller(platform, filename, hashStr, data); err != nil {
		log.Printf("Installer speichern fehlgeschlagen: %v", err)
		writeError(w, http.StatusInternalServerError, "Speichern fehlgeschlagen")
		return
	}

	log.Printf("Installer fuer %s hochgeladen: %s (%d bytes, SHA256: %s)", platform, filename, len(data), hashStr[:16])

	writeJSON(w, http.StatusOK, map[string]interface{}{
		"platform": platform,
		"filename": filename,
		"sha256":   hashStr,
		"size":     len(data),
		"message":  "Installer hochgeladen",
	})
}

// GET /api/v1/installer — Installer-Info (alle Plattformen)
func (h *Handler) getInstallerInfo(w http.ResponseWriter, r *http.Request) {
	all, err := h.db.GetAllInstallerInfo()
	if err != nil || len(all) == 0 {
		writeJSON(w, http.StatusOK, map[string]interface{}{
			"installers": []interface{}{},
		})
		return
	}
	writeJSON(w, http.StatusOK, map[string]interface{}{
		"installers": all,
	})
}

// GET /api/v1/installer/download?platform=freebsd — Installer herunterladen
func (h *Handler) downloadInstaller(w http.ResponseWriter, r *http.Request) {
	platform := r.URL.Query().Get("platform")
	if platform == "" {
		platform = "freebsd"
	}

	filename, hashStr, data, err := h.db.GetInstaller(platform)
	if err != nil {
		writeError(w, http.StatusNotFound, fmt.Sprintf("Kein Installer fuer Plattform '%s' vorhanden", platform))
		return
	}

	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
	w.Header().Set("X-Installer-SHA256", hashStr)
	w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
	w.Write(data)
}
