package infra

import (
	"net/http"
)

// UploadHandler retorna un http.HandlerFunc completo para multipart upload. Compone
// internamente UploadParse + FileValidateType + FileSaveDisk segun cfg.
//
// Comportamiento:
//   - Parsea el multipart con maxSize = cfg.MaxFileSize.
//   - Para cada archivo: valida tipo por magic bytes contra cfg.AllowedTypes,
//     guarda en cfg.BaseDir con FileSaveDisk, sobreescribe ContentType con el
//     MIME real detectado.
//   - Responde 200 con JSON `{"files": [UploadedFile, ...]}`.
//   - Errores: 400 si el parse falla, 415 si algun archivo es de tipo no permitido,
//     500 si falla el guardado.
func UploadHandler(cfg StorageConfig) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		files, err := UploadParse(r, cfg.MaxFileSize)
		if err != nil {
			HTTPErrorResponse(w, HTTPError{
				Status:  http.StatusBadRequest,
				Code:    "parse_error",
				Message: err.Error(),
			})
			return
		}

		var saved []UploadedFile
		for _, pf := range files {
			mime, ok := FileValidateType(pf.Header, cfg.AllowedTypes)
			if !ok {
				HTTPErrorResponse(w, HTTPError{
					Status:  http.StatusUnsupportedMediaType,
					Code:    "invalid_type",
					Message: "tipo no permitido: " + mime,
				})
				return
			}

			uploaded, err := FileSaveDisk(cfg.BaseDir, pf.Filename, pf.Content)
			if err != nil {
				HTTPErrorResponse(w, HTTPError{
					Status:  http.StatusInternalServerError,
					Code:    "save_error",
					Message: err.Error(),
				})
				return
			}
			uploaded.ContentType = mime
			saved = append(saved, uploaded)
		}

		HTTPJSONResponse(w, http.StatusOK, map[string]any{"files": saved})
	}
}
