package nsdxml_test

import (
	"encoding/xml"
	"strings"
	"testing"
	"time"

	"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdxml"
)

func TestNSDDateTimeParse(t *testing.T) {
	cases := []struct {
		in              string
		expectOffset    int
		expectSpecified bool
	}{
		{"2026-03-02T14:30:45(МСК)", 0, false},
		{"2026-03-02T14:30:45(МСК+2)", 2, true},
		{"2026-03-02T14:30:45(МСК-1)", -1, true},
		{"2026-03-02T14:30:45(МСК+12)", 12, true},
	}
	for _, c := range cases {
		c := c
		t.Run(c.in, func(t *testing.T) {
			var d nsdxml.NSDDateTime
			if err := d.UnmarshalText([]byte(c.in)); err != nil {
				t.Fatalf("UnmarshalText: %v", err)
			}
			if d.OffsetSpecified != c.expectSpecified {
				t.Errorf("OffsetSpecified = %v, ожидалось %v", d.OffsetSpecified, c.expectSpecified)
			}
			if d.OffsetHours != c.expectOffset {
				t.Errorf("OffsetHours = %d, ожидалось %d", d.OffsetHours, c.expectOffset)
			}
			out := d.String()
			if out != c.in {
				t.Errorf("String() = %q, ожидалось %q", out, c.in)
			}
		})
	}
}

func TestNSDDateTimeNow(t *testing.T) {
	d := nsdxml.Now()
	if d.OffsetSpecified {
		t.Errorf("Now() не должен задавать смещение")
	}
	if zone, _ := d.Time.Zone(); zone != "МСК" {
		t.Errorf("Now() location зона = %q, ожидалось \"МСК\"", zone)
	}
	if time.Since(d.Time) > time.Minute {
		t.Errorf("Now() вернул время, далёкое от текущего")
	}
}

func TestNSDDateTimeXMLRoundTrip(t *testing.T) {
	type wrap struct {
		XMLName xml.Name           `xml:"wrap"`
		TS      nsdxml.NSDDateTime `xml:"ts"`
	}
	src := `<wrap><ts>2026-03-02T14:30:45(МСК+2)</ts></wrap>`
	var w wrap
	if err := xml.Unmarshal([]byte(src), &w); err != nil {
		t.Fatalf("Unmarshal: %v", err)
	}
	if w.TS.OffsetHours != 2 {
		t.Errorf("OffsetHours = %d, ожидалось 2", w.TS.OffsetHours)
	}
	b, err := xml.Marshal(w)
	if err != nil {
		t.Fatalf("Marshal: %v", err)
	}
	if !strings.Contains(string(b), "2026-03-02T14:30:45(МСК+2)") {
		t.Errorf("Marshal не сохранил формат: %s", b)
	}
}

func TestNSDDateTimeParseErrors(t *testing.T) {
	bad := []string{
		"",
		"2026-13-02T14:30:45(МСК)",
		"2026-03-02 14:30:45(МСК)",
		"2026-03-02T14:30:45",
		"2026-03-02T14:30:45(MSK)",
		"2026-03-02T14:30:45(МСК+200)",
	}
	for _, s := range bad {
		s := s
		t.Run(s, func(t *testing.T) {
			var d nsdxml.NSDDateTime
			if err := d.UnmarshalText([]byte(s)); err == nil {
				t.Errorf("ожидалась ошибка для %q", s)
			}
		})
	}
}
