package telegram

import (
	"testing"
	"time"
)

func TestParse_Start(t *testing.T) {
	cases := []struct {
		in   string
		want string // expected InviteCode; "" means Start is nil
	}{
		{"/start", ""},
		{"/start abc-123", "abc-123"},
		{"/start@acme_x_bot abc-123", "abc-123"},
		{"  /start   abc-123  ", "abc-123"},
	}
	for _, tc := range cases {
		got := Parse(tc.in)
		if got.Start == nil {
			if tc.want != "" {
				t.Errorf("%q: Start is nil, want %q", tc.in, tc.want)
			}
			continue
		}
		if got.Start.InviteCode != tc.want {
			t.Errorf("%q: InviteCode = %q, want %q", tc.in, got.Start.InviteCode, tc.want)
		}
	}
}

func TestParse_Subscribe(t *testing.T) {
	cases := []struct {
		in       string
		source   string
		minSev   string
		badInput bool
	}{
		{"/subscribe prom-prod warning", "prom-prod", "warning", false},
		{"/subscribe prom-prod", "prom-prod", "info", false}, // default min
		{"/subscribe", "", "", true},                         // missing arg
		{"/subscribe prom-prod bogus", "", "", true},         // bad severity
		{"/SUBSCRIBE prom-prod critical", "prom-prod", "critical", false}, // case-insensitive
	}
	for _, tc := range cases {
		got := Parse(tc.in)
		if tc.badInput {
			if got.Subscribe != nil {
				t.Errorf("%q: expected Unknown, got Subscribe %+v", tc.in, got.Subscribe)
			}
			continue
		}
		if got.Subscribe == nil {
			t.Errorf("%q: Subscribe is nil", tc.in)
			continue
		}
		if got.Subscribe.SourceID != tc.source || got.Subscribe.MinSeverity != tc.minSev {
			t.Errorf("%q: Subscribe = %+v, want source=%q min=%q", tc.in, got.Subscribe, tc.source, tc.minSev)
		}
	}
}

func TestParse_Unsubscribe(t *testing.T) {
	c := Parse("/unsubscribe prom-prod")
	if c.Unsubscribe == nil || c.Unsubscribe.SourceID != "prom-prod" {
		t.Errorf("unsubscribe: %+v", c)
	}
	c = Parse("/unsubscribe")
	if c.Unsubscribe != nil {
		t.Errorf("unsubscribe (no arg) should be nil, got %+v", c.Unsubscribe)
	}
}

func TestParse_Preferences(t *testing.T) {
	c := Parse("/preferences")
	if !c.Preferences {
		t.Errorf("expected Preferences=true, got %+v", c)
	}
}

func TestParse_Status(t *testing.T) {
	c := Parse("/status")
	if c.Status == nil || c.Status.Limit != 5 {
		t.Errorf("/status default limit: %+v", c)
	}
	c = Parse("/status 12")
	if c.Status == nil || c.Status.Limit != 12 {
		t.Errorf("/status 12: %+v", c)
	}
	c = Parse("/status 0")  // 0 should fall back to default
	if c.Status == nil || c.Status.Limit != 5 {
		t.Errorf("/status 0: %+v", c)
	}
}

func TestParse_Mute(t *testing.T) {
	c := Parse("/mute 2h")
	if c.Mute == nil || c.Mute.Duration != 2*time.Hour {
		t.Errorf("/mute 2h: %+v", c)
	}
	c = Parse("/mute 30m")
	if c.Mute == nil || c.Mute.Duration != 30*time.Minute {
		t.Errorf("/mute 30m: %+v", c)
	}
	c = Parse("/mute until 18:00")
	if c.Mute == nil || c.Mute.Until.IsZero() {
		t.Errorf("/mute until 18:00: %+v", c.Mute)
	}
	if h := c.Mute.Until.Hour(); h != 18 {
		t.Errorf("/mute until 18:00 hour = %d, want 18", h)
	}
	c = Parse("/mute")
	if c.Mute != nil {
		t.Errorf("/mute (no arg): %+v", c.Mute)
	}
}

func TestParse_Unmute(t *testing.T) {
	c := Parse("/unmute")
	if !c.Unmute {
		t.Errorf("expected Unmute=true, got %+v", c)
	}
}

func TestParse_Unknown(t *testing.T) {
	c := Parse("hello world")
	if c.Unknown == "" {
		t.Error("non-command text should be Unknown")
	}
	c = Parse("/nonsense")
	if c.Unknown == "" {
		t.Error("unknown command should be Unknown")
	}
	c = Parse("")
	if c.Unknown != "" {
		t.Error("empty text should be Unknown=\"\"")
	}
}
