package infra

import (
	"bytes"
	"fmt"
	"os"
	"strings"

	"gopkg.in/yaml.v3"
)

// ParseIssueMd lee un archivo Markdown de issue, extrae y parsea el frontmatter YAML
// en un struct Issue, y devuelve el body (todo lo que va despues del segundo "---").
// FilePath e MtimeNs se rellenan con los valores del archivo en disco.
// Completed se deduce del path (contiene "/completed/").
func ParseIssueMd(path string) (Issue, []byte, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return Issue{}, nil, fmt.Errorf("parse_issue_md: read %s: %w", path, err)
	}

	info, err := os.Stat(path)
	if err != nil {
		return Issue{}, nil, fmt.Errorf("parse_issue_md: stat %s: %w", path, err)
	}

	fm, body, err := splitFrontmatter(data)
	if err != nil {
		return Issue{}, nil, fmt.Errorf("parse_issue_md: %s: %w", path, err)
	}

	var iss Issue
	if err := yaml.Unmarshal(fm, &iss); err != nil {
		return Issue{}, nil, fmt.Errorf("parse_issue_md: yaml %s: %w", path, err)
	}

	iss.FilePath = path
	iss.MtimeNs = info.ModTime().UnixNano()
	iss.Completed = strings.Contains(path, "/completed/")

	return iss, body, nil
}

// splitFrontmatter divide el contenido en bloque YAML y body.
// Espera formato: "---\n<yaml>\n---\n<body>".
// Devuelve el YAML (sin los delimitadores) y el body (incluye el \n posterior al segundo ---).
func splitFrontmatter(data []byte) ([]byte, []byte, error) {
	sep := []byte("---")
	newline := []byte("\n")

	// El archivo debe empezar con "---\n"
	if !bytes.HasPrefix(data, append(sep, '\n')) {
		return nil, nil, fmt.Errorf("missing opening '---' delimiter")
	}

	// Buscar el segundo "---" (en su propia linea)
	rest := data[len(sep)+1:] // avanza pasado el primer "---\n"

	idx := -1
	for i := 0; i <= len(rest)-len(sep); i++ {
		// Debe estar al inicio de linea: posicion 0 o precedido por '\n'
		atLineStart := i == 0 || rest[i-1] == '\n'
		if atLineStart && bytes.Equal(rest[i:i+len(sep)], sep) {
			// El separador debe ir seguido de '\n' o EOF
			end := i + len(sep)
			if end == len(rest) || rest[end] == '\n' {
				idx = i
				break
			}
		}
	}

	if idx == -1 {
		return nil, nil, fmt.Errorf("missing closing '---' delimiter")
	}

	fm := rest[:idx]
	// El body empieza despues del segundo "---\n"
	bodyStart := idx + len(sep)
	if bodyStart < len(rest) && rest[bodyStart] == '\n' {
		bodyStart++
	}
	body := rest[bodyStart:]

	_ = newline
	return fm, body, nil
}
