import React, { useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { Badge, Tabs } from './ui';
import KeywordSuggest from './KeywordSuggest';
import { IconX } from './icons';

const GROUPS = [
	{
		id: 'shorttail',
		label: __('Short-tail', 'ai-rank-suite'),
		hint: __('Broad terms, 1–2 words. The first one is your primary focus keyword.', 'ai-rank-suite'),
		placeholder: __('geo optimization', 'ai-rank-suite'),
	},
	{
		id: 'longtail',
		label: __('Long-tail', 'ai-rank-suite'),
		hint: __('Specific phrases, 3+ words. These win the most AI citations.', 'ai-rank-suite'),
		placeholder: __('how to optimize a website for ChatGPT', 'ai-rank-suite'),
	},
	{
		id: 'geo',
		label: __('AI search prompts', 'ai-rank-suite'),
		hint: __('Questions people actually type into ChatGPT, Claude or Perplexity.', 'ai-rank-suite'),
		placeholder: __('What is GEO optimization and how do I start?', 'ai-rank-suite'),
	},
];

function ScoreDot({ score }) {
	const color = score >= 70 ? 'var(--ars-good)' : score >= 40 ? 'var(--ars-warning)' : 'var(--ars-serious)';
	return (
		<span
			className="inline-block ars-r-sm shrink-0"
			style={{ width: 8, height: 8, background: color }}
			aria-hidden
		/>
	);
}

export default function KeywordEditor({ keywords, coverage, max = 100, onChange, postId = 0 }) {
	const [group, setGroup] = useState('shorttail');
	const [draft, setDraft] = useState('');
	const [bulk, setBulk] = useState(false);
	const [editing, setEditing] = useState(null);
	const [editText, setEditText] = useState('');

	/**
	 * Commit an in-place edit of one keyword.
	 *
	 * An edit that empties the field is a delete by another name, and an edit
	 * onto a phrase already in the list is a duplicate — both resolve to
	 * removing the row rather than to a silent no-op that would leave the old
	 * text on screen and make the edit look like it failed.
	 */
	const commitEdit = (index, save) => {
		if (save) {
			const next = editText.trim();
			const clash = list.some((other, j) => j !== index && other.toLowerCase() === next.toLowerCase());
			set(next && !clash ? list.map((k, j) => (j === index ? next : k)) : list.filter((_, j) => j !== index));
		}
		setEditing(null);
		setEditText('');
	};

	const list = keywords?.[group] || [];
	const meta = GROUPS.find((g) => g.id === group);
	const rows = (coverage?.rows || []).filter((r) => r.group === group);
	const summary = coverage?.summary?.[group];

	const set = (next) => onChange({ ...keywords, [group]: next.slice(0, max) });

	const addFromText = (text) => {
		const parts = text
			.split(/[\n,]/)
			.map((s) => s.trim())
			.filter(Boolean);
		if (!parts.length) return;
		const existing = new Set(list.map((k) => k.toLowerCase()));
		const merged = [...list];
		parts.forEach((p) => {
			if (!existing.has(p.toLowerCase())) {
				existing.add(p.toLowerCase());
				merged.push(p);
			}
		});
		set(merged);
		setDraft('');
	};

	const scoreFor = (keyword) => rows.find((r) => r.keyword === keyword)?.score ?? null;

	const draftCount = draft.split(/[\n,]/).filter((s) => s.trim()).length;

	return (
		<div className="grid gap-3">
			<div className="flex items-center justify-between gap-3 flex-wrap">
				<Tabs
					tabs={GROUPS.map((g) => ({
						id: g.id,
						label: `${g.label} (${(keywords?.[g.id] || []).length})`,
					}))}
					active={group}
					onChange={setGroup}
				/>
				{summary && summary.total > 0 && (
					<Badge tone={summary.coverage >= 70 ? 'good' : summary.coverage >= 40 ? 'warning' : 'serious'}>
						{sprintf(__('%1$s/%2$s covered', 'ai-rank-suite'), summary.covered, summary.total)}
					</Badge>
				)}
			</div>

			<p className="m-0 text-[12.5px]" style={{ color: 'var(--ars-ink-2)' }}>
				{meta.hint}
			</p>

			{bulk ? (
				<div className="grid gap-2">
					<textarea
						rows={6}
						placeholder={`${sprintf(__('One per line — paste up to %d', 'ai-rank-suite'), max)}\n${meta.placeholder}`}
						value={draft}
						onChange={(e) => setDraft(e.target.value)}
					/>
					<div className="flex gap-2">
						<button type="button" className="ars-btn ars-btn-primary" onClick={() => addFromText(draft)}>
							{sprintf(_n('Add %d keyword', 'Add %d keywords', draftCount, 'ai-rank-suite'), draftCount)}
						</button>
						<button
							type="button"
							className="ars-btn ars-btn-ghost"
							onClick={() => {
								setBulk(false);
								setDraft('');
							}}
						>{__('Cancel', 'ai-rank-suite')}</button>
					</div>
				</div>
			) : (
				<form
					className="flex gap-2"
					onSubmit={(e) => {
						e.preventDefault();
						addFromText(draft);
					}}
				>
					<input
						type="text"
						placeholder={meta.placeholder}
						value={draft}
						onChange={(e) => setDraft(e.target.value)}
						disabled={list.length >= max}
					/>
					<button type="submit" className="ars-btn ars-btn-ghost" disabled={!draft.trim() || list.length >= max}>{__('Add', 'ai-rank-suite')}</button>
					<button type="button" className="ars-btn ars-btn-ghost" onClick={() => setBulk(true)}>{__('Bulk', 'ai-rank-suite')}</button>
				</form>
			)}

			{/* Let the engine fill the list.
			    Scoped to the open tab, because the three groups are three
			    different questions — short terms, long phrases, and the
			    questions people put to an assistant. Suggestions arrive as
			    chips; nothing is added until one is clicked. */}
			{list.length < max && (
				<KeywordSuggest
					postId={postId}
					group={group}
					taken={list}
					label={
						group === 'geo'
							? __('Suggest prompts with AI', 'ai-rank-suite')
							: group === 'longtail'
								? __('Suggest long-tail with AI', 'ai-rank-suite')
								: __('Suggest keywords with AI', 'ai-rank-suite')
					}
					onPick={(k) => addFromText(k)}
				/>
			)}

			<div className="flex items-center justify-between text-[11.5px]" style={{ color: 'var(--ars-ink-3)' }}>
				<span>
					{list.length} / {max}
				</span>
				{list.length > 0 && (
					<button
						type="button"
						className="border-0 bg-transparent cursor-pointer p-0 text-[11.5px]"
						style={{ color: 'var(--ars-serious)' }}
						onClick={() => set([])}
					>{__('Clear all', 'ai-rank-suite')}</button>
				)}
			</div>

			{list.length === 0 ? (
				<p className="m-0 text-[12.5px]" style={{ color: 'var(--ars-ink-3)' }}>{__('No keywords in this group yet.', 'ai-rank-suite')}</p>
			) : (
				<div
					className="grid gap-1 max-h-[260px] overflow-y-auto pr-1"
					style={{ scrollbarWidth: 'thin' }}
				>
					{list.map((keyword, i) => {
						const score = scoreFor(keyword);
						const row = rows.find((r) => r.keyword === keyword);
						return (
							<div
								key={`${keyword}-${i}`}
								className="flex items-center gap-2 ars-r-md px-2.5 py-1.5"
								style={{ background: 'var(--ars-surface-2)' }}
							>
								{score !== null && <ScoreDot score={score} />}

								{/* Promote in place. The primary is simply the first
								    entry, and reordering by drag is a lot of machinery
								    for a decision that is one click. */}
								{group === 'shorttail' && (
									<button
										type="button"
										title={i === 0 ? __('Primary — coverage is scored against this one', 'ai-rank-suite') : __('Make primary', 'ai-rank-suite')}
										disabled={i === 0}
										onClick={() => set([keyword, ...list.filter((_, j) => j !== i)])}
										className="border-0 bg-transparent p-0 shrink-0"
										style={{
											cursor: i === 0 ? 'default' : 'pointer',
											color: i === 0 ? 'var(--ars-brand)' : 'var(--ars-ink-3)',
											fontSize: 12,
											lineHeight: 1,
										}}
									>
										{i === 0 ? '★' : '☆'}
									</button>
								)}

								{editing === i ? (
									// Correcting a typo used to mean deleting the keyword
									// and retyping the whole phrase. Enter or blur commits,
									// Escape restores.
									<input
										type="text"
										autoFocus
										value={editText}
										onChange={(e) => setEditText(e.target.value)}
										onBlur={() => commitEdit(i, true)}
										onKeyDown={(e) => {
											if (e.key === 'Enter') {
												e.preventDefault();
												commitEdit(i, true);
											} else if (e.key === 'Escape') {
												e.preventDefault();
												commitEdit(i, false);
											}
										}}
										className="flex-1"
										style={{ height: 26, fontSize: 12.5, padding: '2px 6px' }}
									/>
								) : (
									<span
										className="flex-1 text-[12.5px] truncate"
										title={__('Click to edit', 'ai-rank-suite')}
										style={{ cursor: 'text' }}
										onClick={() => {
											setEditing(i);
											setEditText(keyword);
										}}
									>
										{keyword}
									</span>
								)}
								{row && (
									<span
										className="text-[11px] tabular-nums shrink-0"
										style={{ color: 'var(--ars-ink-3)' }}
										title={
											group === 'geo'
												? __('Share of prompt terms found on this page', 'ai-rank-suite')
												: sprintf(__('%1$s× in text · %2$s%% density', 'ai-rank-suite'), row.occurrences, row.density)
										}
									>
										{group === 'geo'
											? Object.keys(row.signals)
													.filter((k) => row.signals[k])
													.join(', ') || __('not answered', 'ai-rank-suite')
											: Object.keys(row.signals)
													.filter((k) => row.signals[k])
													.join(', ') || __('not found', 'ai-rank-suite')}
									</span>
								)}
								<button
									type="button"
									aria-label={sprintf(__('Remove %s', 'ai-rank-suite'), keyword)}
									className="border-0 bg-transparent cursor-pointer p-0 shrink-0"
									style={{ color: 'var(--ars-ink-3)' }}
									onClick={() => set(list.filter((_, j) => j !== i))}
								>
									<IconX size={13} />
								</button>
							</div>
						);
					})}
				</div>
			)}
		</div>
	);
}
