describe("note2cal", function()
	-- Load the module for each test
	local note2cal = require("note2cal.init")
	local current_date = os.date("%Y-%m-%d")

	describe("parse_time", function()
		it("should parse 24-hour format with only hours", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("6-7")
			assert.same({ 6, 0, 7, 0 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("15-16")
			assert.same({ 15, 0, 16, 0 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("6-19")
			assert.same({ 6, 0, 19, 0 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse simple 24-hour format with hours and minutes", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3:15-4:30")
			assert.same({ 3, 15, 4, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("16:15-17:30")
			assert.same({ 16, 15, 17, 30 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse AM/PM format with only hours", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3pm-4pm")
			assert.same({ 15, 0, 16, 0 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3p-4p")
			assert.same({ 15, 0, 16, 0 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3a-4p")
			assert.same({ 3, 0, 16, 0 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse AM/PM format with hours and minutes", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3:15pm-4:30pm")
			assert.same({ 15, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3:15am-4:30pm")
			assert.same({ 3, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3:15p-4:30p")
			assert.same({ 15, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3:15a-4:30p")
			assert.same({ 3, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse compact format with AM/PM", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315pm-430pm")
			assert.same({ 15, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315am-430pm")
			assert.same({ 3, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315p-430p")
			assert.same({ 15, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315a-430p")
			assert.same({ 3, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse compact format without AM/PM", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("3-430")
			assert.same({ 3, 0, 4, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315-430")
			assert.same({ 3, 15, 4, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("315-1630")
			assert.same({ 3, 15, 16, 30 }, { start_h, start_m, end_h, end_m })
		end)

		it("should parse military format", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("0300-1630")
			assert.same({ 3, 0, 16, 30 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("1500-1630")
			assert.same({ 15, 0, 16, 30 }, { start_h, start_m, end_h, end_m })
		end)

		-- Mixed formats
		it("should parse mixed formats", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("6-715")
			assert.same({ 6, 0, 7, 15 }, { start_h, start_m, end_h, end_m })
			local start_h, start_m, end_h, end_m = note2cal.parse_time("730-1230pm")
			assert.same({ 7, 30, 12, 30 }, { start_h, start_m, end_h, end_m })
		end)

		-- Edge cases
		it("should handle noon correctly", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("12pm-1pm")
			assert.same({ 12, 0, 13, 0 }, { start_h, start_m, end_h, end_m })
		end)

		it("should handle midnight correctly", function()
			local start_h, start_m, end_h, end_m = note2cal.parse_time("12am-1am")
			assert.same({ 0, 0, 1, 0 }, { start_h, start_m, end_h, end_m })
		end)

		-- Invalid formats
		it("should return nil for invalid formats", function()
			assert.is_nil(note2cal.parse_time("invalid"))
			assert.is_nil(note2cal.parse_time(""))
			assert.is_nil(note2cal.parse_time("25:00-26:00")) -- invalid hours
		end)
	end)

	describe("extract_event_details", function()
		it("should extract event title, date, and time correctly with date", function()
			local title, date, time = note2cal.extract_event_details("Meeting @ 2025-01-20 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("2025-01-20", date)
			assert.are.equal("3pm-4pm", time)
		end)

		it("should extract event title and assume current date when no date is provided", function()
			local title, date, time = note2cal.extract_event_details("Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal(current_date, date)
			assert.are.equal("3pm-4pm", time)
		end)

		it("should return nil for invalid format", function()
			local title, date, time = note2cal.extract_event_details("Invalid format")
			assert.is_nil(title)
			assert.is_nil(date)
			assert.is_nil(time)

			local title, date, time = note2cal.extract_event_details("Invalid format email@example.com")
			assert.is_nil(title)
			assert.is_nil(date)
			assert.is_nil(time)
		end)

		it("should ignore markdown tasks and bullets", function()
			local title, _, time = note2cal.extract_event_details("- [ ] Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("3pm-4pm", time)

			local title, _, time = note2cal.extract_event_details("* [ ] Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("3pm-4pm", time)

			local title, date, time = note2cal.extract_event_details("- Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("3pm-4pm", time)

			local title, date, time = note2cal.extract_event_details("* Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("3pm-4pm", time)
		end)

		it("should ignore indentation", function()
			local title, date, time = note2cal.extract_event_details("  Meeting @ 3pm-4pm")
			assert.are.equal("Meeting", title)
			assert.are.equal("3pm-4pm", time)
		end)
	end)
end)
