import { useState } from 'react';
import { MapPin, Check } from 'lucide-react';
import { Button } from '@/components/ui/button';
import ConversationalChat from '@/features/chat/ConversationalChat';
import OnboardingLayout from '@/features/onboarding/OnboardingLayout';
import { post, getWordPressConfig } from '@/api/client';
import { logError } from '@/errors/logger';
import { getErrorMessage } from '@/utils/errorMessages';

// The three editable business-profile fields, in canonical order. Each maps to
// a chat question (QUESTIONS, below) and to a label shown on the selector step.
const EDITABLE_FIELDS = [
	{ id: 'business', label: 'What you do' },
	{ id: 'customers', label: 'Who you serve' },
	{ id: 'address', label: 'Where you operate' },
];

const QUESTIONS = {
	business: {
		id: 'business',
		type: 'text',
		question: 'How would you describe your business?',
		example:
			'Example: "A cozy local café offering specialty coffee and homemade pastries."',
		field: 'businessDescription',
		acknowledgment: 'Perfect! That gives me a good sense of what you do.',
	},
	customers: {
		id: 'customers',
		type: 'text',
		question: 'Who are your typical customers?',
		example:
			'Example: "Families and young professionals looking for fresh, handmade baked goods."',
		field: 'targetCustomer',
		acknowledgment:
			"Great! That helps me understand who you're trying to reach.",
	},
	address: {
		id: 'address',
		type: 'address',
		question:
			'Do you have a physical address for your business? If you do, start typing it and pick it from the list. If not, just say no.',
		example: 'Example: "456 Oak Avenue, Rivertown, USA"',
		field: 'location',
		acknowledgment: 'Perfect! I have everything I need.',
	},
};

/**
 * FieldSelector
 *
 * Shown when the user clicks "Needs fixing" on the confirmation card. Lets them
 * pick which fields to correct (with an "All" shortcut) before the chat starts,
 * so the chat only re-asks the fields they actually want to change.
 */
const FieldSelector = ({ onSubmit, onCancel }) => {
	const [selected, setSelected] = useState([]);
	const allSelected = selected.length === EDITABLE_FIELDS.length;

	const toggleField = (id) => {
		setSelected((prev) =>
			prev.includes(id)
				? prev.filter((field) => field !== id)
				: [...prev, id]
		);
	};

	const toggleAll = () => {
		setSelected(allSelected ? [] : EDITABLE_FIELDS.map((field) => field.id));
	};

	const renderRow = (label, isChecked, onClick, isAll = false) => (
		<button
			type="button"
			onClick={onClick}
			aria-pressed={isChecked}
			className="w-full flex items-center gap-3 p-4 border border-border rounded-sm text-left hover:bg-muted/50 transition-colors"
		>
			<span
				className={`w-5 h-5 shrink-0 rounded-sm border flex items-center justify-center transition-colors ${
					isChecked
						? 'bg-foreground border-foreground'
						: 'border-border'
				}`}
			>
				{isChecked && <Check className="w-3.5 h-3.5 text-background" />}
			</span>
			<span
				className={`${isAll ? 'small-semibold' : 'paragraph-regular'} text-foreground`}
			>
				{label}
			</span>
		</button>
	);

	return (
		<OnboardingLayout title="What would you like to change?">
			<div className="mb-6">
				<p className="paragraph-regular text-foreground">
					Pick what you'd like to update. I'll only ask about the
					things you select.
				</p>
			</div>

			<div className="bg-card border border-border rounded-sm p-6 mb-6">
				<div className="space-y-3 mb-6">
					{renderRow('All', allSelected, toggleAll, true)}
					{EDITABLE_FIELDS.map((field) =>
						renderRow(
							field.label,
							selected.includes(field.id),
							() => toggleField(field.id)
						)
					)}
				</div>

				<div className="flex gap-3">
					<Button
						size="lg"
						onClick={() => onSubmit(selected)}
						disabled={selected.length === 0}
						className="bg-foreground text-background hover:bg-foreground/90"
					>
						Continue
					</Button>
					<Button size="lg" variant="outline" onClick={onCancel}>
						Back
					</Button>
				</div>
			</div>
		</OnboardingLayout>
	);
};

/**
 * BusinessChat Step
 *
 * Flow:
 * 1. If all inferred → show confirmation card directly
 *    If some missing → chat asks only missing fields → then show confirmation card
 * 2. On confirmation card:
 *    - "Looks good!" → save & advance
 *    - "Let me fix this" → chat with ALL fields → then show confirmation card again
 */
const BusinessChat = ({ onNext, data }) => {
	const profileResponse = data.businessProfileResponse || {};
	const understood = profileResponse.understood === true;

	const hasDescription = !!profileResponse.description;
	const hasCustomers = !!profileResponse.customer;
	const hasLocation = profileResponse.isLocal && !!profileResponse.location;
	const allInferred =
		understood && hasDescription && hasCustomers && hasLocation;

	const { endpoints } = getWordPressConfig();
	const [isSubmitting, setIsSubmitting] = useState(false);
	const [error, setError] = useState(null);

	// The merged profile data shown in the confirmation card
	const [profileData, setProfileData] = useState({
		businessDescription: profileResponse.description || '',
		targetCustomer: profileResponse.customer || '',
		isLocal: profileResponse.isLocal ?? false,
		location: profileResponse.location || '',
		// Full Google Place object captured when the user picks a prediction in
		// the address turn (null for free-text / no physical location).
		locationComplete: profileResponse.locationComplete || null,
	});

	// View state: 'confirm' | 'select-fields' | 'chat'
	// Start on confirm if all inferred, otherwise chat first
	const [view, setView] = useState(allInferred ? 'confirm' : 'chat');

	// Fields the user explicitly chose to fix on the selector step.
	// null = chat opened automatically (Flavio didn't fully understand), so we
	// fall back to asking the missing/not-understood fields.
	const [fieldsToEdit, setFieldsToEdit] = useState(null);

	const buildQuestions = () => {
		// Explicit edit: user picked specific fields on the selector step.
		if (fieldsToEdit) {
			return EDITABLE_FIELDS.filter((field) =>
				fieldsToEdit.includes(field.id)
			).map((field) => QUESTIONS[field.id]);
		}

		// Auto-start: chat opened because Flavio didn't fully understand. Ask
		// everything when not understood, otherwise just the missing fields.
		const shouldAskAll = !understood;
		const ids = [];
		if (shouldAskAll || !hasDescription) ids.push('business');
		if (shouldAskAll || !hasCustomers) ids.push('customers');
		if (shouldAskAll || !hasLocation) ids.push('address');
		return ids.map((id) => QUESTIONS[id]);
	};

	// Chat finished → merge responses with inferred data, show confirmation
	const handleChatComplete = (responses) => {
		setProfileData((prev) => {
			const hasValidAddress =
				responses.location &&
				responses.location.toLowerCase() !== 'no';
			// Only recompute isLocal when the address was actually asked;
			// otherwise keep whatever the user already has (partial edits).
			const isLocal =
				'location' in responses ? hasValidAddress : prev.isLocal;

			return {
				...prev,
				...responses,
				isLocal,
			};
		});
		setView('confirm');
	};

	// User confirms → save to backend and advance
	const handleConfirm = async () => {
		setIsSubmitting(true);
		setError(null);

		try {
			await post(endpoints.businessInfo, {
				businessDescription: profileData.businessDescription,
				targetCustomer: profileData.targetCustomer,
				isLocal: profileData.isLocal,
				location: profileData.location,
				locationComplete: profileData.locationComplete,
			});

			await post(endpoints.onboardingBusinessProfile, {
				description: profileData.businessDescription,
				customer: profileData.targetCustomer,
				isLocal: profileData.isLocal,
				location: profileData.location,
			});

			onNext({
				businessDescription: profileData.businessDescription,
				targetCustomer: profileData.targetCustomer,
				isLocal: profileData.isLocal,
				location: profileData.location,
				locationComplete: profileData.locationComplete,
			});
		} catch (err) {
			logError(err, {
				action: 'confirm_business_profile',
				component: 'BusinessChat',
			});
			setError(
				getErrorMessage(
					err,
					'Failed to save your business info. Please try again.'
				)
			);
		} finally {
			setIsSubmitting(false);
		}
	};

	// User wants to correct → let them pick which fields to fix first
	const handleEdit = () => {
		setView('select-fields');
	};

	// User picked fields on the selector step → chat asks only those
	const handleFieldsSelected = (selected) => {
		setFieldsToEdit(selected);
		setView('chat');
	};

	if (view === 'select-fields') {
		return (
			<FieldSelector
				onSubmit={handleFieldsSelected}
				onCancel={() => setView('confirm')}
			/>
		);
	}

	if (view === 'chat') {
		const config = getWordPressConfig();

		return (
			<div className="flex flex-col w-full max-w-4xl mx-auto px-8">
				<header className="flex items-start gap-4 shrink-0 mb-4">
					<img
						src={`${config.pluginUrl}js/public/onboarding.svg`}
						alt="Flavio mascot"
						className="w-[64px] h-[64px] shrink-0 mt-1"
						width="64"
						height="64"
					/>
					<div>
						<h1 className="heading-h1 leading-tight mt-0! mb-2">
							Here's my understanding of your business
						</h1>
						<p className="paragraph-regular text-foreground">
							{fieldsToEdit
								? "Let's update what you'd like to change."
								: 'I need a bit more info to get things right.'}
						</p>
					</div>
				</header>

				<div className="flex-1 min-h-0 pl-[80px]">
					<ConversationalChat
						key={
							fieldsToEdit
								? `edit-${fieldsToEdit.join('-')}`
								: 'fill-missing'
						}
						questions={buildQuestions()}
						onComplete={handleChatComplete}
						initialValues={{}}
						completionMessage="Got it! Let me put that together…"
					/>
				</div>
			</div>
		);
	}

	// Confirmation view
	return (
		<OnboardingLayout title="Here's my understanding of your business">
			<div className="mb-6">
				<p className="paragraph-regular text-foreground">
					Does this look right? I'll use this information to guide my
					work.
				</p>
			</div>

			<div className="bg-card border border-border rounded-sm p-6 mb-6">
				<div className="space-y-4 mb-6">
					<div>
						<p className="small-semibold text-foreground uppercase tracking-wide mb-1 mt-0!">
							What you do
						</p>
						<p className="paragraph-regular text-foreground">
							{profileData.businessDescription}
						</p>
					</div>

					<div>
						<p className="small-semibold text-foreground uppercase tracking-wide mb-1">
							Who you serve
						</p>
						<p className="paragraph-regular text-foreground">
							{profileData.targetCustomer}
						</p>
					</div>

					{profileData.isLocal && profileData.location ? (
						<div>
							<p className="small-semibold text-foreground uppercase tracking-wide mb-1">
								Where you operate
							</p>
							<p className="paragraph-regular text-foreground flex items-center gap-1.5">
								<MapPin className="w-4 h-4 shrink-0" />
								{profileData.location}
							</p>
						</div>
					) : (
						<div>
							<p className="small-semibold text-foreground uppercase tracking-wide mb-1">
								Where you operate
							</p>
							<p className="paragraph-regular text-foreground flex items-center gap-1.5">
								<MapPin className="w-4 h-4 shrink-0" />
								No physical location
							</p>
						</div>
					)}
				</div>

				<div className="flex gap-3">
					<Button
						size="lg"
						onClick={handleConfirm}
						disabled={isSubmitting}
						className="bg-foreground text-background hover:bg-foreground/90"
					>
						{isSubmitting ? 'Saving...' : 'Looks good!'}
					</Button>
					<Button
						size="lg"
						variant="outline"
						onClick={handleEdit}
						disabled={isSubmitting}
					>
						Needs fixing
					</Button>
				</div>
			</div>

			{error && (
				<div className="mt-4 p-4 bg-destructive/10 border border-destructive/20 rounded-lg">
					<p className="text-sm text-destructive">{error}</p>
				</div>
			)}
		</OnboardingLayout>
	);
};

export default BusinessChat;
