import Testing
import GRDB
@testable import MailStore
@testable import Models

@Suite("MailStore Search & Queries")
struct SearchTests {
	func makeStore() throws -> MailStore {
		try MailStore(dbWriter: DatabaseSetup.openInMemoryDatabase())
	}

	func seedData(_ store: MailStore) throws {
		try store.insertAccount(AccountRecord(
			id: "acc1", name: "Personal", email: "me@example.com",
			imapHost: "imap.example.com", imapPort: 993
		))
		try store.upsertMailbox(MailboxRecord(
			id: "mb1", accountId: "acc1", name: "INBOX", uidValidity: 1, uidNext: 100
		))
		try store.insertMessages([
			MessageRecord(
				id: "m1", accountId: "acc1", mailboxId: "mb1", uid: 1,
				messageId: "msg001@example.com", inReplyTo: nil, refs: nil,
				subject: "Quarterly planning meeting", fromAddress: "alice@example.com",
				fromName: "Alice Johnson", toAddresses: nil, ccAddresses: nil,
				date: "2024-03-08T10:00:00Z", snippet: "Let's discuss Q2 goals",
				bodyText: "Let's discuss Q2 goals and roadmap priorities.", bodyHtml: nil,
				isRead: false, isFlagged: false, size: 1024
			),
			MessageRecord(
				id: "m2", accountId: "acc1", mailboxId: "mb1", uid: 2,
				messageId: "msg002@example.com", inReplyTo: nil, refs: nil,
				subject: "Invoice #4521", fromAddress: "billing@vendor.com",
				fromName: "Billing Dept", toAddresses: nil, ccAddresses: nil,
				date: "2024-03-07T09:00:00Z", snippet: "Please find attached",
				bodyText: "Your invoice for March is attached.", bodyHtml: nil,
				isRead: true, isFlagged: false, size: 2048
			),
		])
	}

	@Test("FTS5 search finds messages by subject")
	func searchBySubject() throws {
		let store = try makeStore()
		try seedData(store)
		let results = try store.search(query: "quarterly")
		#expect(results.count == 1)
		#expect(results[0].id == "m1")
	}

	@Test("FTS5 search finds messages by body text")
	func searchByBody() throws {
		let store = try makeStore()
		try seedData(store)
		let results = try store.search(query: "roadmap")
		#expect(results.count == 1)
		#expect(results[0].id == "m1")
	}

	@Test("FTS5 search finds messages by sender name")
	func searchBySender() throws {
		let store = try makeStore()
		try seedData(store)
		let results = try store.search(query: "alice")
		#expect(results.count == 1)
		#expect(results[0].fromName == "Alice Johnson")
	}

	@Test("FTS5 search returns empty for no matches")
	func searchNoMatch() throws {
		let store = try makeStore()
		try seedData(store)
		let results = try store.search(query: "nonexistent")
		#expect(results.isEmpty)
	}

	@Test("thread summaries include unread count and senders")
	func threadSummaries() throws {
		let store = try makeStore()
		try seedData(store)
		let reconstructor = ThreadReconstructor(store: store)
		let messages = try store.messages(mailboxId: "mb1")
		try reconstructor.processMessages(messages)
		let summaries = try store.threadSummaries(accountId: "acc1")
		#expect(summaries.count == 2)
		// First thread (most recent) should be "Quarterly planning meeting"
		#expect(summaries[0].subject == "Quarterly planning meeting")
		#expect(summaries[0].unreadCount == 1)
	}
}
