package lib

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestSendTemplate(t *testing.T) {
	// Create a mailer with templates loaded
	m := &Mailer{enabled: true}
	
	// Find the email templates directory
	templateDir := "../portal/emails"
	if _, err := os.Stat(templateDir); os.IsNotExist(err) {
		templateDir = "portal/emails"
		if _, err := os.Stat(templateDir); os.IsNotExist(err) {
			t.Skipf("email templates directory not found, skipping test")
		}
	}

	absPath, err := filepath.Abs(templateDir)
	if err != nil {
		t.Fatalf("failed to get absolute path: %v", err)
	}

	if err := m.LoadTemplates(absPath); err != nil {
		t.Fatalf("failed to load templates: %v", err)
	}

	tests := []struct {
		name     string
		tmplName string
		data     any
		expected []string
	}{
		{
			name:     "invite",
			tmplName: "invite.html",
			data: InviteData{
				InviterName:   "Sarah Mitchell",
				InviterOrg:    "Goldman Sachs",
				ProjectName:   "Project Phoenix",
				InviteURL:     "https://app.muskepo.com/invite/abc123",
				RecipientName: "John Smith",
				ExpiresIn:     "7 days",
			},
			expected: []string{"Sarah Mitchell", "Goldman Sachs", "Project Phoenix", "Accept Invitation", "DEALSPACE"},
		},
		{
			name:     "tasks_assigned",
			tmplName: "tasks_assigned.html",
			data: TasksAssignedData{
				RecipientName: "John Smith",
				ProjectName:   "Project Phoenix",
				Count:         3,
				Tasks: []TaskItem{
					{Title: "FIN-001: Audited financials", DueDate: "March 15", Priority: "high"},
				},
				TasksURL: "https://app.muskepo.com/app/tasks",
			},
			expected: []string{"John Smith", "Project Phoenix", "3 new tasks", "View My Tasks"},
		},
		{
			name:     "answer_submitted",
			tmplName: "answer_submitted.html",
			data: AnswerSubmittedData{
				AnswererName:   "John Smith",
				RequestTitle:   "FIN-001: Audited financials",
				WorkstreamName: "Finance",
				ReviewURL:      "https://app.muskepo.com/app/review/ans_xyz123",
			},
			expected: []string{"John Smith", "FIN-001: Audited financials", "Finance", "Review Answer"},
		},
		{
			name:     "answer_approved",
			tmplName: "answer_approved.html",
			data: AnswerApprovedData{
				RequestTitle: "FIN-001: Audited financials",
				Published:    true,
			},
			expected: []string{"Your answer was approved", "FIN-001: Audited financials", "Published to Data Room"},
		},
		{
			name:     "answer_rejected",
			tmplName: "answer_rejected.html",
			data: AnswerRejectedData{
				RequestTitle: "FIN-001: Audited financials",
				Reason:       "Need final audited version",
				RequestURL:   "https://app.muskepo.com/app/tasks/req_001",
			},
			expected: []string{"Your answer needs revision", "FIN-001: Audited financials", "View Feedback"},
		},
		{
			name:     "request_forwarded",
			tmplName: "request_forwarded.html",
			data: RequestForwardedData{
				SenderName:   "John Smith",
				RequestTitle: "FIN-003: AR aging report",
				RequestURL:   "https://app.muskepo.com/app/tasks/req_003",
				DueDate:      "March 18, 2026",
				HasDueDate:   true,
			},
			expected: []string{"John Smith", "FIN-003: AR aging report", "View Request", "March 18, 2026"},
		},
		{
			name:     "welcome",
			tmplName: "welcome.html",
			data: WelcomeData{
				RecipientName: "John Smith",
				TasksURL:      "https://app.muskepo.com/app/tasks",
			},
			expected: []string{"Welcome to Dealspace", "John Smith", "Your inbox is your home", "Ask Aria", "Go to My Tasks"},
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			result, err := m.RenderTemplate(tc.tmplName, tc.data)
			if err != nil {
				t.Fatalf("RenderTemplate(%s) failed: %v", tc.tmplName, err)
			}

			if len(result) == 0 {
				t.Errorf("RenderTemplate(%s) returned empty result", tc.tmplName)
			}

			for _, expected := range tc.expected {
				if !strings.Contains(result, expected) {
					t.Errorf("RenderTemplate(%s) missing expected string: %q", tc.tmplName, expected)
				}
			}

			if !strings.Contains(result, "<!DOCTYPE html>") {
				t.Errorf("RenderTemplate(%s) missing DOCTYPE", tc.tmplName)
			}
		})
	}
}

func TestMailerDisabled(t *testing.T) {
	m := &Mailer{enabled: false}

	err := m.Send("test@example.com", "Test Subject", "<html>test</html>")
	if err != nil {
		t.Errorf("Send on disabled mailer should return nil, got: %v", err)
	}

	err = m.SendTemplate("test@example.com", "Test Subject", "invite.html", nil)
	if err != nil {
		t.Errorf("SendTemplate on disabled mailer should return nil, got: %v", err)
	}
}

func TestMailerEnabled(t *testing.T) {
	enabled := &Mailer{enabled: true}
	disabled := &Mailer{enabled: false}

	if !enabled.Enabled() {
		t.Error("enabled mailer should return true for Enabled()")
	}
	if disabled.Enabled() {
		t.Error("disabled mailer should return false for Enabled()")
	}
}

func TestBase64Encode(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		{"", ""},
		{"f", "Zg=="},
		{"fo", "Zm8="},
		{"foo", "Zm9v"},
		{"foobar", "Zm9vYmFy"},
	}

	for _, tc := range tests {
		result := base64Encode(tc.input)
		if result != tc.expected {
			t.Errorf("base64Encode(%q) = %q, want %q", tc.input, result, tc.expected)
		}
	}
}

func TestEmailFuncs(t *testing.T) {
	funcs := emailFuncs()

	gt := funcs["gt"].(func(int, int) bool)
	if !gt(5, 3) {
		t.Error("gt(5, 3) should be true")
	}

	sub := funcs["sub"].(func(int, int) int)
	if sub(10, 3) != 7 {
		t.Error("sub(10, 3) should be 7")
	}

	truncate := funcs["truncate"].(func(string, int) string)
	if truncate("hello world", 5) != "hello..." {
		t.Error("truncate('hello world', 5) should be 'hello...'")
	}
}
