package rest_http

import (
	"bytes"
	"encoding/json"
	"io"
	"mime/multipart"
	"net/http"
	"net/textproto"

	"git.ali33.ru/fcg-xvii/rest"
)

func NewRequestOut(req rest.IRequest) *RequestOut {
	return &RequestOut{
		IRequest: req,
	}
}

// Response реализует объект ответа
type RequestOut struct {
	Err rest.IErrorArgs
	rest.IRequest
}

func (s *RequestOut) RClose() {
	if s.IRequest != nil {
		s.IRequest.RClose()
	}
}

// Send отправляет запрос серверу
func (s *RequestOut) Write(writer io.Writer) rest.IErrorArgs {
	w := writer.(http.ResponseWriter)
	//log.Println("SEND...")
	defer s.RClose()
	if s.Err != nil {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(500)
		w.Write([]byte(s.Err.Map().JSON()))
		return nil
	}
	// Если есть файлы, то используем multipart
	files := s.RFiles()
	if len(files) > 0 {
		var b bytes.Buffer
		writer := multipart.NewWriter(&b)
		w.Header().Set("Content-Type", writer.FormDataContentType())

		// Добавляем JSON-данные как часть
		partHeader := make(textproto.MIMEHeader)
		partHeader.Set("Content-Type", "application/json")
		partHeader.Set("Content-Disposition", `form-data; name="data"`)
		dataPart, err := writer.CreatePart(partHeader)
		if err != nil {
			return rest.ErrorMessage("ErrResponsePartDataCreate", err.Error())
		}
		if err := json.NewEncoder(dataPart).Encode(s.RData()); err != nil {
			return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error())
		}

		// Добавляем файлы
		for filename, file := range files {
			part, err := writer.CreateFormFile("file", filename)
			if err != nil {
				return rest.ErrorMessage("ErrResponsePartFileCreate", err.Error())
			}
			if _, err := io.Copy(part, file); err != nil {
				return rest.ErrorMessage("ErrResponsePartFileCopy", err.Error())
			}
		}

		// Закрываем multipart writer
		if err := writer.Close(); err != nil {
			return rest.ErrorMessage("ErrResponsePartFileClose", err.Error())
		}

		// Отправляем multipart response
		w.Header().Set("Content-Type", writer.FormDataContentType())
		w.Write(b.Bytes())
	} else {
		// Если нет файлов, просто отправляем JSON
		w.Header().Set("Content-Type", "application/json")
		if err := json.NewEncoder(w).Encode(s.RData()); err != nil {
			return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error())
		}
	}

	return nil
}

// Успрешный ответ

func ResponseSuccess(req rest.IRequest) rest.IRequestOut {
	return &RequestOut{
		IRequest: req,
	}
}

func ResponseError(err rest.IErrorArgs) rest.IRequestOut {
	return &RequestOut{
		Err: err,
	}
}