import SwiftUI
import Models

struct ThreadDetailView: View {
	let thread: ThreadSummary?
	let messages: [MessageSummary]
	let linkedTasks: [TaskSummary]
	var onComposeRequest: (ComposeMode) -> Void

	var body: some View {
		Group {
			if let thread {
				ScrollView {
					VStack(alignment: .leading, spacing: 0) {
						Text(thread.subject ?? "(No Subject)")
							.font(.title2)
							.fontWeight(.semibold)
							.padding()

						Divider()

						// Merge messages and tasks, sorted by date
						ForEach(sortedEntries) { entry in
							switch entry {
							case .message(let message):
								MessageView(message: message)
								Divider()
							case .task(let task):
								LinkedTaskView(task: task)
								Divider()
							}
						}
					}
				}
				.toolbar {
					ToolbarItemGroup(placement: .automatic) {
						Button {
							if let last = messages.last {
								onComposeRequest(.reply(to: last))
							}
						} label: {
							Label("Reply", systemImage: "arrowshape.turn.up.left")
						}
						.keyboardShortcut("r", modifiers: .command)
						.help("Reply (⌘R)")

						Button {
							if let last = messages.last {
								onComposeRequest(.replyAll(to: last))
							}
						} label: {
							Label("Reply All", systemImage: "arrowshape.turn.up.left.2")
						}
						.keyboardShortcut("r", modifiers: [.shift, .command])
						.help("Reply All (⇧⌘R)")

						Button {
							if let last = messages.last {
								onComposeRequest(.forward(of: last))
							}
						} label: {
							Label("Forward", systemImage: "arrowshape.turn.up.right")
						}
						.keyboardShortcut("f", modifiers: .command)
						.help("Forward (⌘F)")
					}
				}
			} else {
				ContentUnavailableView(
					"No Thread Selected",
					systemImage: "envelope",
					description: Text("Select a thread to read")
				)
			}
		}
	}

	// MARK: - Merged timeline

	private enum TimelineEntry: Identifiable {
		case message(MessageSummary)
		case task(TaskSummary)

		var id: String {
			switch self {
			case .message(let msg): "msg-\(msg.id)"
			case .task(let task): "task-\(task.id)"
			}
		}

		var date: Date {
			switch self {
			case .message(let msg): msg.date
			case .task(let task): task.createdAt
			}
		}
	}

	private var sortedEntries: [TimelineEntry] {
		var entries: [TimelineEntry] = []
		entries.append(contentsOf: messages.map { .message($0) })
		entries.append(contentsOf: linkedTasks.map { .task($0) })
		return entries.sorted { $0.date < $1.date }
	}
}

// MARK: - Linked Task View

struct LinkedTaskView: View {
	let task: TaskSummary

	var body: some View {
		HStack(spacing: 10) {
			Image(systemName: statusIcon)
				.font(.title3)
				.foregroundStyle(statusColor)

			VStack(alignment: .leading, spacing: 4) {
				Text(task.summary)
					.fontWeight(.medium)
					.strikethrough(task.status == .completed || task.status == .cancelled)

				HStack(spacing: 8) {
					StatusBadge(status: task.status)

					if let due = task.dueDate {
						Text("Due \(due, style: .date)")
							.font(.caption)
							.foregroundStyle(due < Date() ? .red : .secondary)
					}
				}
			}

			Spacer()

			Text(task.createdAt, style: .relative)
				.font(.caption)
				.foregroundStyle(.secondary)
		}
		.padding()
		.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 8))
		.padding(.horizontal)
		.padding(.vertical, 4)
	}

	private var statusIcon: String {
		switch task.status {
		case .completed: "checkmark.circle.fill"
		case .cancelled: "xmark.circle"
		case .inProcess: "circle.dotted.circle"
		case .needsAction: "circle"
		}
	}

	private var statusColor: Color {
		switch task.status {
		case .completed: .green
		case .cancelled: .red
		case .inProcess: .orange
		case .needsAction: .primary
		}
	}
}

struct StatusBadge: View {
	let status: TaskStatus

	var body: some View {
		Text(status.rawValue)
			.font(.caption2)
			.fontWeight(.medium)
			.padding(.horizontal, 6)
			.padding(.vertical, 2)
			.background(badgeColor.opacity(0.15), in: Capsule())
			.foregroundStyle(badgeColor)
	}

	private var badgeColor: Color {
		switch status {
		case .completed: .green
		case .cancelled: .red
		case .inProcess: .orange
		case .needsAction: .blue
		}
	}
}

struct MessageView: View {
	let message: MessageSummary
	@State private var showHTML = false

	var body: some View {
		VStack(alignment: .leading, spacing: 8) {
			HStack {
				Text(message.from?.displayName ?? "Unknown")
					.fontWeight(.semibold)
				Spacer()
				if message.bodyHtml != nil {
					Toggle(isOn: $showHTML) {
						Text("HTML")
							.font(.caption)
					}
					.toggleStyle(.button)
					.controlSize(.small)
				}
				Text(message.date, style: .date)
					.font(.caption)
					.foregroundStyle(.secondary)
			}

			if !message.to.isEmpty {
				Text("To: \(message.to.map(\.displayName).joined(separator: ", "))")
					.font(.caption)
					.foregroundStyle(.secondary)
			}

			if showHTML, let html = message.bodyHtml {
				MessageWebView(html: html)
					.frame(minHeight: 200)
			} else if let bodyText = message.bodyText {
				Text(bodyText)
					.font(.body)
					.textSelection(.enabled)
			} else if let snippet = message.snippet {
				Text(snippet)
					.font(.body)
					.foregroundStyle(.secondary)
					.italic()
			} else {
				Text("Loading body…")
					.font(.body)
					.foregroundStyle(.tertiary)
			}
		}
		.padding()
	}
}
