package ocr_client

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/textproto"
	"time"
)

type Client struct {
	pythonServiceURL string
	httpClient       *http.Client
}

func NewClient(pythonServiceURL string) *Client {
	return &Client{
		pythonServiceURL: pythonServiceURL,
		httpClient: &http.Client{
			// OCR может быть долгим, ставим таймаут побольше (например, 30 сек)
			Timeout: 30 * time.Second,
		},
	}
}

// ProcessImage отправляет изображение в Python и возвращает сырые данные
func (c *Client) ProcessImage(ctx context.Context, imageData []byte, filename string) (*RecognitionResult, error) {
	// 1. Создаем буфер для multipart формы
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	// Создаем заголовок части вручную, чтобы прописать Content-Type: image/jpeg
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="image"; filename="%s"`, filename))
	h.Set("Content-Type", "image/jpeg") // Явно указываем, что это картинка

	part, err := writer.CreatePart(h)
	if err != nil {
		return nil, fmt.Errorf("create part error: %w", err)
	}

	// Записываем байты картинки
	if _, err := io.Copy(part, bytes.NewReader(imageData)); err != nil {
		return nil, fmt.Errorf("copy file error: %w", err)
	}

	// Закрываем writer, чтобы записать boundary
	if err := writer.Close(); err != nil {
		return nil, fmt.Errorf("writer close error: %w", err)
	}

	// 2. Создаем запрос
	req, err := http.NewRequestWithContext(ctx, "POST", c.pythonServiceURL+"/recognize", body)
	if err != nil {
		return nil, fmt.Errorf("create request error: %w", err)
	}

	// Важно: Content-Type с boundary
	req.Header.Set("Content-Type", writer.FormDataContentType())

	// 3. Отправляем
	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("ocr service request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		bodyBytes, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("ocr service error (code %d): %s", resp.StatusCode, string(bodyBytes))
	}

	// 4. Парсим ответ
	var result RecognitionResult
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("json decode error: %w", err)
	}

	return &result, nil
}
