package feichibridge

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"os/exec"
	"regexp"
	"strings"
	"time"
)

var captchaPattern = regexp.MustCompile(`^[0-9A-Z]{4}$`)

type CaptchaSolver interface {
	Solve(context.Context, []byte) (string, error)
}

type DockerCaptchaSolver struct {
	Image   string
	Timeout time.Duration
}

func (s DockerCaptchaSolver) Solve(ctx context.Context, image []byte) (string, error) {
	if len(image) == 0 {
		return "", errors.New("captcha image is empty")
	}
	if strings.TrimSpace(s.Image) == "" {
		return "", errors.New("captcha OCR image is required")
	}
	timeout := s.Timeout
	if timeout <= 0 {
		timeout = 20 * time.Second
	}
	solveCtx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()
	command := exec.CommandContext(
		solveCtx,
		"docker", "run", "--rm", "--network=none", "-i", strings.TrimSpace(s.Image),
	)
	command.Stdin = bytes.NewReader(image)
	var stderr bytes.Buffer
	command.Stderr = &stderr
	output, err := command.Output()
	if err != nil {
		if solveCtx.Err() != nil {
			return "", fmt.Errorf("captcha OCR timed out: %w", solveCtx.Err())
		}
		return "", fmt.Errorf("captcha OCR failed: %w: %s", err, strings.TrimSpace(stderr.String()))
	}
	code := strings.ToUpper(strings.TrimSpace(string(output)))
	if !captchaPattern.MatchString(code) {
		return "", fmt.Errorf("captcha OCR returned invalid result %q", code)
	}
	return code, nil
}
