package api

import (
	"encoding/base64"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync/atomic"
	"time"

	"github.com/muyue/muyue/internal/config"
)

var imageDir string

func init() {
	dir, err := config.ConfigDir()
	if err != nil {
		dir = "/tmp/muyue"
	}
	imageDir = filepath.Join(dir, "images")
	os.MkdirAll(imageDir, 0755)
}

var imageCounter uint64

func saveImage(dataURI, filename, mimeType string) (string, error) {
	parts := strings.SplitN(dataURI, ",", 2)
	if len(parts) != 2 {
		return "", fmt.Errorf("invalid data URI")
	}
	encoded := parts[1]

	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		return "", fmt.Errorf("base64 decode: %w", err)
	}
	if len(decoded) > 10*1024*1024 {
		return "", fmt.Errorf("image too large (max 10MB)")
	}

	id := fmt.Sprintf("%d-%d", time.Now().UnixMilli(), atomic.AddUint64(&imageCounter, 1))
	ext := ".png"
	switch mimeType {
	case "image/jpeg":
		ext = ".jpg"
	case "image/webp":
		ext = ".webp"
	}

	filePath := filepath.Join(imageDir, id+ext)
	if err := os.WriteFile(filePath, decoded, 0600); err != nil {
		return "", fmt.Errorf("write image: %w", err)
	}

	return id + ext, nil
}

func imagePath(id string) string {
	return filepath.Join(imageDir, filepath.Base(id))
}

func cleanupImages(ids []string) {
	for _, id := range ids {
		p := imagePath(id)
		if err := os.Remove(p); err != nil && !os.IsNotExist(err) {
			_ = err
		}
	}
}

func (s *Server) handleServeImage(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		writeError(w, "GET only", http.StatusMethodNotAllowed)
		return
	}

	id := strings.TrimPrefix(r.URL.Path, "/api/images/")
	if id == "" {
		writeError(w, "image id required", http.StatusBadRequest)
		return
	}

	filePath := imagePath(id)
	if _, err := os.Stat(filePath); err != nil {
		writeError(w, "image not found", http.StatusNotFound)
		return
	}

	ext := strings.ToLower(filepath.Ext(id))
	switch ext {
	case ".jpg", ".jpeg":
		w.Header().Set("Content-Type", "image/jpeg")
	case ".png":
		w.Header().Set("Content-Type", "image/png")
	case ".webp":
		w.Header().Set("Content-Type", "image/webp")
	default:
		w.Header().Set("Content-Type", "application/octet-stream")
	}
	w.Header().Set("Cache-Control", "public, max-age=86400")

	http.ServeFile(w, r, filePath)
}
