/**
 * Column Selector — chips bar, category tabs, checkbox grid.
 *
 * @package RawTypeOE
 */

import { useCallback, useEffect, useMemo, useRef, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
	Badge,
	Button,
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
	Checkbox,
	Label,
	Notice,
	Popover,
	SearchField,
	Skeleton,
	SkeletonGroup,
	Spinner,
	Switch,
	TextField,
	ToggleGroup,
	Tooltip,
} from '@rawtype/ui';

/* ─── Skeleton loader ─────────────────────────────────────────────────────── */

function ColumnsSkeleton() {
	return (
		<SkeletonGroup>
			{ Array.from( { length: 8 } ).map( ( _, i ) => (
				<Skeleton key={ i } width="100%" height={ 28 } />
			) ) }
		</SkeletonGroup>
	);
}

/* ─── Group title helper ──────────────────────────────────────────────────── */

function getGroupTitle( groupKey ) {
	const map = {
		customer: __( 'Customer', 'rawtype-order-exporter-woocommerce' ),
		order: __( 'Order', 'rawtype-order-exporter-woocommerce' ),
		product: __( 'Product', 'rawtype-order-exporter-woocommerce' ),
		custom_fields: __( 'Custom fields', 'rawtype-order-exporter-woocommerce' ),
	};
	return map[ groupKey ] || groupKey.charAt( 0 ).toUpperCase() + groupKey.slice( 1 );
}

/* ─── Selected Chip ───────────────────────────────────────────────────────── */

function SelectedChip( {
	column,
	onRemove,
	onRename,
	renameOpen,
	onOpenRename,
	onCloseRename,
	onDragStart,
	onDragOver,
	onDrop,
	isDragging,
	isDragOver,
} ) {
	const inputRef = useRef( null );
	const displayLabel = column.customLabel || column.label;

	let className = 'roe-chip';
	if ( isDragging ) {
		className += ' roe-chip--dragging';
	}
	if ( isDragOver ) {
		className += ' roe-chip--dragover';
	}

	useEffect( () => {
		if ( renameOpen && inputRef.current ) {
			inputRef.current.focus();
			inputRef.current.select();
		}
	}, [ renameOpen ] );

	const handleKeyDown = ( e ) => {
		if ( 'Enter' === e.key || 'Escape' === e.key ) {
			onCloseRename();
		}
	};

	return (
		<Popover.Root open={ renameOpen } onOpenChange={ ( open ) => {
			if ( open ) {
				onOpenRename();
			} else {
				onCloseRename();
			}
		} }>
			<Popover.Trigger asChild>
				<span
					className={ className }
					draggable
					onDragStart={ onDragStart }
					onDragOver={ onDragOver }
					onDrop={ onDrop }
				>
					<span className="roe-chip-label">{ displayLabel }</span>
					<button
						type="button"
						className="roe-chip-remove"
						onClick={ ( e ) => {
							e.stopPropagation();
							onRemove( column.key );
						} }
						aria-label={ sprintf(
							/* translators: %s: selected column label */
							__( 'Remove %s', 'rawtype-order-exporter-woocommerce' ),
							displayLabel,
						) }
					>
						&times;
					</button>
				</span>
			</Popover.Trigger>
			<Popover.Content side="bottom" align="start" className="roe-chip-rename-popover">
				<div className="roe-chip-rename-content">
					<Label htmlFor={ 'rename-' + column.key } className="roe-chip-rename-label">
						{ __( 'Rename column', 'rawtype-order-exporter-woocommerce' ) }
					</Label>
					<TextField
						ref={ inputRef }
						id={ 'rename-' + column.key }
						value={ column.customLabel || '' }
						onChange={ ( e ) => onRename( column.key, e.target.value ) }
						onKeyDown={ handleKeyDown }
						placeholder={ column.label }
					/>
					<span className="roe-chip-rename-hint">
						{ sprintf(
							/* translators: %s: original column label */
							__( 'Original: %s', 'rawtype-order-exporter-woocommerce' ),
							column.label,
						) }
					</span>
				</div>
			</Popover.Content>
		</Popover.Root>
	);
}

/* ─── Main Component ──────────────────────────────────────────────────────── */

export default function ColumnSelector( {
	entity,
	availableColumns,
	columnsLoading,
	columnsError,
	columnsRefreshing,
	selectedColumns,
	onToggleColumn,
	onSelectAll,
	onDeselectAll,
	onResetDefaults,
	onRenameColumn,
	onReorderColumns,
	onRemoveColumn,
	showInternalFields,
	onToggleShowInternalFields,
	onRefreshCustomFields,
	customFieldsRefreshing,
	onNext,
	onPrev,
} ) {
	const [ search, setSearch ] = useState( '' );
	const [ activeGroup, setActiveGroup ] = useState( '' );
	const [ renameKey, setRenameKey ] = useState( null );
	const [ dragIndex, setDragIndex ] = useState( null );
	const [ dragOverIdx, setDragOverIdx ] = useState( null );
	const dragOverRef = useRef( null );

	// Group all available columns.
	const allGrouped = useMemo( () => {
		const groups = {};
		availableColumns.forEach( ( col ) => {
			if ( ! groups[ col.group ] ) {
				groups[ col.group ] = [];
			}
			groups[ col.group ].push( col );
		} );
		return groups;
	}, [ availableColumns ] );

	const groupKeys = useMemo( () => Object.keys( allGrouped ), [ allGrouped ] );

	// Filter columns by search + active group.
	const filteredColumns = useMemo( () => {
		let cols = availableColumns;

		if ( activeGroup ) {
			cols = cols.filter( ( col ) => col.group === activeGroup );
		}

		if ( search ) {
			const q = search.toLowerCase();
			cols = cols.filter( ( col ) =>
				col.label.toLowerCase().indexOf( q ) !== -1 ||
				col.key.toLowerCase().indexOf( q ) !== -1,
			);
		}

		return cols;
	}, [ availableColumns, activeGroup, search ] );

	// Counts per group (respecting search filter).
	const groupCounts = useMemo( () => {
		const counts = {};
		const q = search ? search.toLowerCase() : '';

		groupKeys.forEach( ( key ) => {
			const cols = allGrouped[ key ] || [];
			counts[ key ] = q
				? cols.filter( ( col ) =>
						col.label.toLowerCase().indexOf( q ) !== -1 ||
						col.key.toLowerCase().indexOf( q ) !== -1,
				  ).length
				: cols.length;
		} );

		return counts;
	}, [ allGrouped, groupKeys, search ] );

	const isSelected = useCallback(
		( columnKey ) => selectedColumns.some( ( c ) => c.key === columnKey ),
		[ selectedColumns ],
	);

	// Chip drag handlers.
	const handleChipDragStart = useCallback( ( index ) => {
		setDragIndex( index );
	}, [] );

	const handleChipDragOver = useCallback( ( e, index ) => {
		e.preventDefault();
		dragOverRef.current = index;
		setDragOverIdx( index );
	}, [] );

	const handleChipDrop = useCallback( ( e ) => {
		e.preventDefault();
		if ( null === dragIndex || null === dragOverRef.current ) {
			return;
		}
		const reordered = [ ...selectedColumns ];
		const dragged = reordered.splice( dragIndex, 1 )[ 0 ];
		reordered.splice( dragOverRef.current, 0, dragged );
		onReorderColumns( reordered );
		setDragIndex( null );
		setDragOverIdx( null );
		dragOverRef.current = null;
	}, [ dragIndex, selectedColumns, onReorderColumns ] );

	// Set first group active when groups load.
	useEffect( () => {
		if ( ! activeGroup && groupKeys.length > 0 ) {
			setActiveGroup( groupKeys[ 0 ] );
		}
	}, [ groupKeys, activeGroup ] );

	if ( columnsLoading ) {
		return (
			<Card className="roe-column-selector">
				<CardContent>
					<ColumnsSkeleton />
				</CardContent>
			</Card>
		);
	}

	if ( columnsError ) {
		return (
			<Card className="roe-column-selector">
				<CardContent>
					<Notice type="error">
						{ __( 'Could not load available columns', 'rawtype-order-exporter-woocommerce' ) }
					</Notice>
				</CardContent>
			</Card>
		);
	}

	const isRefreshing = !! columnsRefreshing || !! customFieldsRefreshing;

	return (
		<Card className="roe-column-selector">
			<CardHeader>
				<CardTitle>
					{ __( 'Columns', 'rawtype-order-exporter-woocommerce' ) }
					{ selectedColumns.length > 0 && (
						<Badge variant="default" className="roe-column-title-count">
							{ selectedColumns.length }
						</Badge>
					) }
				</CardTitle>
				<CardDescription>
					{ __( 'Select and reorder the columns that will appear in your file. Click a selected column to rename it.', 'rawtype-order-exporter-woocommerce' ) }
				</CardDescription>
			</CardHeader>

			<CardContent>
				<div className="roe-column-selector-layout">

					{ /* ── Selected Chips Bar ── */ }
					<div className="roe-chips-bar">
						{ 0 === selectedColumns.length ? (
							<span className="roe-chips-empty">
								{ __( 'Click the columns below to select them', 'rawtype-order-exporter-woocommerce' ) }
							</span>
						) : (
							<>
								{ selectedColumns.map( ( col, index ) => (
									<SelectedChip
										key={ col.key }
										column={ col }
										onRemove={ onRemoveColumn }
										onRename={ onRenameColumn }
										renameOpen={ renameKey === col.key }
										onOpenRename={ () => setRenameKey( col.key ) }
										onCloseRename={ () => setRenameKey( null ) }
										onDragStart={ () => handleChipDragStart( index ) }
										onDragOver={ ( e ) => handleChipDragOver( e, index ) }
										onDrop={ handleChipDrop }
										isDragging={ dragIndex === index }
										isDragOver={ dragOverIdx === index }
									/>
								) ) }
							</>
						) }
					</div>

					{ /* ── Toolbar ── */ }
					<div className="roe-column-toolbar">
						<SearchField
							value={ search }
							onChange={ setSearch }
							placeholder={ __( 'Search columns...', 'rawtype-order-exporter-woocommerce' ) }
							className="roe-column-search"
						/>
						<div className="roe-column-toolbar-right">
							{ 'cross-entity' !== entity && (
								<>
									<Label htmlFor="roe-show-internal-fields" className="roe-column-toolbar-label">
										{ __( 'Internal', 'rawtype-order-exporter-woocommerce' ) }
									</Label>
									<Switch
										id="roe-show-internal-fields"
										checked={ !! showInternalFields }
										onCheckedChange={ onToggleShowInternalFields }
									/>
									<Button
										type="button"
										variant="outline"
										size="sm"
										onClick={ onRefreshCustomFields }
										disabled={ !! customFieldsRefreshing }
									>
										{ customFieldsRefreshing
											? __( 'Refreshing…', 'rawtype-order-exporter-woocommerce' )
											: __( 'Refresh', 'rawtype-order-exporter-woocommerce' ) }
									</Button>
								</>
							) }
						</div>
					</div>

					<div className="roe-column-toolbar-bulk">
						<Button type="button" variant="ghost" size="sm" onClick={ onSelectAll }>
							{ __( 'Select all', 'rawtype-order-exporter-woocommerce' ) }
						</Button>
						<Button type="button" variant="ghost" size="sm" onClick={ onDeselectAll }>
							{ __( 'Deselect', 'rawtype-order-exporter-woocommerce' ) }
						</Button>
						<Button type="button" variant="ghost" size="sm" onClick={ onResetDefaults }>
							{ __( 'Reset', 'rawtype-order-exporter-woocommerce' ) }
						</Button>
						{ isRefreshing && <Spinner size="sm" /> }
					</div>

					{ /* ── Category Tabs ── */ }
					<div className="roe-column-tabs">
						<ToggleGroup.Root
							type="single"
							variant="pills"
							size="sm"
							className="roe-column-tabs-group"
							value={ activeGroup }
							onValueChange={ ( val ) => setActiveGroup( val || '' ) }
						>
							{ groupKeys.map( ( key ) => (
								<ToggleGroup.Item key={ key } value={ key } className="roe-column-tab-item">
									<span className="roe-column-tab-label">{ getGroupTitle( key ) }</span>
									<Badge variant="inset">{ groupCounts[ key ] || 0 }</Badge>
								</ToggleGroup.Item>
							) ) }
						</ToggleGroup.Root>
					</div>

					{ /* ── Column Grid ── */ }
					<div className={ 'roe-column-grid' + ( isRefreshing ? ' roe-column-grid--refreshing' : '' ) }>
						{ filteredColumns.length === 0 ? (
							<div className="roe-column-grid-empty">
								{ __( 'No columns found. Try another group or clear the search.', 'rawtype-order-exporter-woocommerce' ) }
							</div>
						) : (
							filteredColumns.map( ( col ) => {
								const selected = isSelected( col.key );
								return (
									<label
										key={ col.key }
										htmlFor={ 'roe-col-' + col.key }
										className={ 'roe-column-grid-item' + ( selected ? ' roe-column-grid-item--selected' : '' ) }
									>
										<Checkbox
											id={ 'roe-col-' + col.key }
											checked={ selected }
											onCheckedChange={ () => onToggleColumn( col ) }
										/>
										<span className="roe-column-grid-item-label">{ col.label }</span>
										{ col.badge && (
											<Badge variant="accent" className="roe-column-pro-badge">
												{ col.badge }
											</Badge>
										) }
										{ col.source && (
											<Badge variant="default" className="roe-column-source-badge">
												{ col.source.toUpperCase() }
											</Badge>
										) }
										{ col.serialized && (
											<Tooltip content={ __( 'This field contains serialized data. It will be exported as JSON text.', 'rawtype-order-exporter-woocommerce' ) }>
												<span className="roe-column-serialized-hint">i</span>
											</Tooltip>
										) }
									</label>
								);
							} )
						) }
					</div>

				</div>
			</CardContent>

			<CardFooter className="roe-column-actions">
				<Button type="button" variant="outline" onClick={ onPrev }>
					{ __( 'Previous', 'rawtype-order-exporter-woocommerce' ) }
				</Button>
				<Button
					type="button"
					onClick={ onNext }
					disabled={ 0 === selectedColumns.length }
				>
					{ sprintf(
						/* translators: %d: number of selected columns */
						__( 'Next (%d columns)', 'rawtype-order-exporter-woocommerce' ),
						selectedColumns.length,
					) }
				</Button>
			</CardFooter>
		</Card>
	);
}
