"use client";

import { Mail, Plus, X } from "lucide-react";
import type React from "react";
import { useState } from "react";
import { cx } from "../lib/utils";
import { OnboardingButton } from "../primitives/onboarding-button";
import { OnboardingInput } from "../primitives/onboarding-input";
import { OnboardingLabel } from "../primitives/onboarding-label";
import {
	OnboardingSelect,
	OnboardingSelectContent,
	OnboardingSelectItem,
	OnboardingSelectTrigger,
	OnboardingSelectValue,
} from "../primitives/onboarding-select";

export interface TeamRole {
	value: string;
	label: string;
	description?: string;
}

export interface TeamMember {
	email: string;
	role: string;
}

export interface TeamInviteStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string;
	/** Available roles for team members */
	roles: TeamRole[];
	/** Default role for new members */
	defaultRole?: string;
	/** Default members to pre-populate */
	defaultMembers?: TeamMember[];
	/** Minimum number of invites required (0 = optional) */
	minInvites?: number;
	/** Maximum number of invites allowed */
	maxInvites?: number;
	/** Called when invites change */
	onInvitesChange?: (members: TeamMember[]) => void;
	/** Called when the user submits the form */
	onSubmit: (members: TeamMember[]) => void | Promise<void>;
	/** Text for the submit button */
	submitText?: string;
	/** Text shown while submitting */
	loadingText?: string;
	/** Text for skip button (if minInvites is 0) */
	skipText?: string;
	/** Optional back button config */
	backButton?: {
		text: string;
		onClick: () => void;
	};
}

export function TeamInviteStep({
	title = "Invite your team",
	description = "Add team members to collaborate on this project.",
	roles,
	defaultRole,
	defaultMembers,
	minInvites = 0,
	maxInvites = 10,
	onInvitesChange,
	onSubmit,
	submitText = "Send Invites",
	loadingText = "Sending...",
	skipText = "Skip for now",
	backButton,
}: TeamInviteStepProps) {
	const [members, setMembers] = useState<TeamMember[]>(
		defaultMembers && defaultMembers.length > 0
			? defaultMembers
			: [{ email: "", role: defaultRole || roles[0]?.value || "" }],
	);
	const [errors, setErrors] = useState<Record<number, string>>({});
	const [loading, setLoading] = useState(false);

	const validateEmail = (email: string): boolean => {
		if (!email) return true; // Empty is okay, we filter them out
		const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
		return emailRegex.test(email);
	};

	const handleEmailChange = (index: number, email: string) => {
		const newMembers = [...members];
		newMembers[index].email = email;
		setMembers(newMembers);

		// Validate
		if (email && !validateEmail(email)) {
			setErrors((prev) => ({ ...prev, [index]: "Please enter a valid email" }));
		} else {
			setErrors((prev) => {
				const newErrors = { ...prev };
				delete newErrors[index];
				return newErrors;
			});
		}

		onInvitesChange?.(newMembers.filter((m) => m.email.trim()));
	};

	const handleRoleChange = (index: number, role: string) => {
		const newMembers = [...members];
		newMembers[index].role = role;
		setMembers(newMembers);
		onInvitesChange?.(newMembers.filter((m) => m.email.trim()));
	};

	const addMember = () => {
		if (members.length < maxInvites) {
			setMembers([
				...members,
				{ email: "", role: defaultRole || roles[0]?.value || "" },
			]);
		}
	};

	const removeMember = (index: number) => {
		if (members.length > 1) {
			const newMembers = members.filter((_, i) => i !== index);
			setMembers(newMembers);
			// Clean up errors
			setErrors((prev) => {
				const newErrors: Record<number, string> = {};
				Object.entries(prev).forEach(([key, value]) => {
					const keyNum = parseInt(key);
					if (keyNum < index) {
						newErrors[keyNum] = value;
					} else if (keyNum > index) {
						newErrors[keyNum - 1] = value;
					}
				});
				return newErrors;
			});
			onInvitesChange?.(newMembers.filter((m) => m.email.trim()));
		}
	};

	const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
		e.preventDefault();

		// Validate all emails
		const newErrors: Record<number, string> = {};
		members.forEach((member, index) => {
			if (member.email && !validateEmail(member.email)) {
				newErrors[index] = "Please enter a valid email";
			}
		});

		if (Object.keys(newErrors).length > 0) {
			setErrors(newErrors);
			return;
		}

		const validMembers = members.filter((m) => m.email.trim());

		if (validMembers.length < minInvites) {
			// This shouldn't happen if button is disabled properly
			return;
		}

		setLoading(true);
		try {
			await onSubmit(validMembers);
		} finally {
			setLoading(false);
		}
	};

	const handleSkip = async () => {
		setLoading(true);
		try {
			await onSubmit([]);
		} finally {
			setLoading(false);
		}
	};

	const validMemberCount = members.filter(
		(m) => m.email.trim() && validateEmail(m.email),
	).length;
	const hasErrors = Object.keys(errors).length > 0;
	const canSubmit = validMemberCount >= minInvites && !hasErrors;
	const canSkip = minInvites === 0;

	return (
		<main className="mx-auto p-4">
			<div
				style={{ animationDuration: "500ms" }}
				className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
			>
				<h1 className="text-2xl font-semibold text-foreground sm:text-xl">
					{title}
				</h1>
				<p className="mt-6 text-muted-foreground sm:text-sm">{description}</p>
			</div>

			<form onSubmit={handleSubmit} className="mt-8">
				<div className="space-y-4">
					{members.map((member, index) => (
						<div
							key={index}
							className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
							style={{
								animationDuration: "400ms",
								animationDelay: `${index * 50}ms`,
								animationFillMode: "backwards",
							}}
						>
							<div className="flex items-center gap-3">
								<Mail className="h-4 w-4 shrink-0 text-muted-foreground" />
								<div className="flex-1">
									<OnboardingLabel
										className="sr-only"
										htmlFor={`email-${index}`}
									>
										Email address
									</OnboardingLabel>
									<OnboardingInput
										id={`email-${index}`}
										type="email"
										placeholder="colleague@company.com"
										value={member.email}
										onChange={(e) => handleEmailChange(index, e.target.value)}
										aria-invalid={!!errors[index]}
										className={cx(errors[index] && "border-destructive")}
									/>
								</div>
								<div className="w-28">
									<OnboardingLabel
										className="sr-only"
										htmlFor={`role-${index}`}
									>
										Role
									</OnboardingLabel>
									<OnboardingSelect
										value={member.role}
										onValueChange={(value) => handleRoleChange(index, value)}
									>
										<OnboardingSelectTrigger id={`role-${index}`}>
											<OnboardingSelectValue />
										</OnboardingSelectTrigger>
										<OnboardingSelectContent>
											{roles.map((role) => (
												<OnboardingSelectItem
													key={role.value}
													value={role.value}
												>
													{role.label}
												</OnboardingSelectItem>
											))}
										</OnboardingSelectContent>
									</OnboardingSelect>
								</div>
								{members.length > 1 && (
									<button
										type="button"
										onClick={() => removeMember(index)}
										className="shrink-0 rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground"
										aria-label="Remove member"
									>
										<X className="h-4 w-4" />
									</button>
								)}
							</div>
							{errors[index] && (
								<p className="mt-1 ml-7 text-sm text-destructive">
									{errors[index]}
								</p>
							)}
						</div>
					))}
				</div>

				{members.length < maxInvites && (
					<button
						type="button"
						onClick={addMember}
						className="mt-4 flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-border py-3 text-sm text-muted-foreground transition-colors hover:border-primary hover:text-primary"
					>
						<Plus className="h-4 w-4" />
						Add another team member
					</button>
				)}

				<div
					className={cx(
						"mt-8 flex",
						backButton ? "justify-between" : "justify-end",
					)}
				>
					{backButton && (
						<OnboardingButton
							type="button"
							variant="ghost"
							onClick={backButton.onClick}
						>
							{backButton.text}
						</OnboardingButton>
					)}
					<div className="flex gap-3">
						{canSkip && validMemberCount === 0 && (
							<OnboardingButton
								type="button"
								variant="ghost"
								onClick={handleSkip}
								disabled={loading}
							>
								{skipText}
							</OnboardingButton>
						)}
						<OnboardingButton
							className="disabled:bg-muted disabled:text-muted-foreground"
							type="submit"
							disabled={!canSubmit || loading}
							aria-disabled={!canSubmit || loading}
							isLoading={loading}
						>
							{loading
								? loadingText
								: validMemberCount > 0
									? `${submitText} (${validMemberCount})`
									: submitText}
						</OnboardingButton>
					</div>
				</div>
			</form>
		</main>
	);
}
