import useIsMobile from '@hooks/useIsMobile';
import { Card, Checkbox, Empty, Pagination, Spin, Table } from 'antd';
import PropTypes from 'prop-types';
import { useEffect, useState } from 'react';

/**
 * ResponsiveTable — renders a normal Ant <Table> on tablet/desktop and a stacked
 * list of cards on phones (below the `md` breakpoint, 768px), driven by the SAME
 * `columns` definition. Wide data tables squeeze to ~1 char/column or force
 * horizontal scrolling on mobile; the card view reuses each column's `render` so
 * rows stay readable and tappable without duplicating cell logic.
 *
 * Drop-in for <Table>: pass the usual columns/dataSource/rowKey/loading/pagination/
 * rowSelection props. On desktop everything is forwarded to <Table> untouched.
 *
 * Card mapping per row:
 *  - the `title`/`name` column (or the first column) becomes the card heading;
 *  - a trailing actions column (empty title, or key/dataIndex of action[s]) becomes
 *    the card footer;
 *  - remaining columns render as "Label: value" rows (empty values are skipped).
 */
const getKey = (record, rowKey, index) => {
	if (typeof rowKey === 'function') return rowKey(record);
	if (rowKey && record?.[rowKey] != null) return record[rowKey];
	return index;
};

const isActionsColumn = (col) => {
	const id = String(col.key ?? col.dataIndex ?? '').toLowerCase();
	return id === 'action' || id === 'actions' || (!col.title && !!col.render);
};

const isPrimaryColumn = (col) => {
	const id = String(col.dataIndex ?? col.key ?? '').toLowerCase();
	// exact `title`/`name`, or a suffix like `abstract_title` / `attendee_name`
	return /(^|_)(title|name)$/.test(id);
};

const cellValue = (col, record, index) =>
	typeof col.render === 'function'
		? col.render(record?.[col.dataIndex], record, index)
		: record?.[col.dataIndex];

const MobileCards = ({
	columns,
	dataSource,
	rowKey,
	loading,
	pagination,
	rowSelection,
	locale,
}) => {
	const pageSize = pagination?.pageSize ?? 20;
	const [page, setPage] = useState(1);
	const rows = Array.isArray(dataSource) ? dataSource : [];

	// Keep the current page in range when the data shrinks (filters, deletes).
	useEffect(() => {
		const maxPage = Math.max(1, Math.ceil(rows.length / pageSize));
		if (page > maxPage) setPage(maxPage);
	}, [rows.length, pageSize, page]);

	if (loading) {
		return (
			<div style={{ textAlign: 'center', padding: '40px 0' }}>
				<Spin />
			</div>
		);
	}
	if (rows.length === 0) {
		return (
			<Empty
				description={locale?.emptyText}
				image={Empty.PRESENTED_IMAGE_SIMPLE}
				style={{ padding: '24px 0' }}
			/>
		);
	}

	const visible = columns.filter((c) => c && c.title !== null);
	const primary =
		visible.find(isPrimaryColumn) ||
		visible.find((c) => !isActionsColumn(c)) ||
		visible[0];
	const actions = visible.filter(isActionsColumn);
	const bodyCols = visible.filter((c) => c !== primary && !isActionsColumn(c));

	const paged =
		pagination === false
			? rows
			: rows.slice((page - 1) * pageSize, page * pageSize);
	const selectedKeys = rowSelection?.selectedRowKeys ?? [];

	const toggle = (key, checked) => {
		if (!rowSelection?.onChange) return;
		const next = checked
			? [...selectedKeys, key]
			: selectedKeys.filter((k) => k !== key);
		rowSelection.onChange(next);
	};

	return (
		<div>
			{paged.map((record, i) => {
				const key = getKey(record, rowKey, (page - 1) * pageSize + i);
				return (
					<Card
						key={key}
						size='small'
						style={{ marginBottom: 12, borderRadius: 10 }}
						styles={{ body: { padding: 14 } }}
					>
						<div
							style={{
								display: 'flex',
								alignItems: 'flex-start',
								gap: 10,
								marginBottom: bodyCols.length || actions.length ? 10 : 0,
							}}
						>
							{rowSelection && (
								<Checkbox
									checked={selectedKeys.includes(key)}
									onChange={(e) => toggle(key, e.target.checked)}
									style={{ marginTop: 2 }}
								/>
							)}
							<div style={{ flex: 1, minWidth: 0, fontWeight: 600 }}>
								{primary ? cellValue(primary, record, i) : null}
							</div>
						</div>

						{bodyCols.map((col) => {
							const value = cellValue(col, record, i);
							if (value == null || value === '') return null;
							return (
								<div
									key={col.key ?? col.dataIndex}
									style={{
										display: 'flex',
										justifyContent: 'space-between',
										gap: 12,
										padding: '3px 0',
										fontSize: 13,
									}}
								>
									<span style={{ color: '#8c8c8c', flexShrink: 0 }}>
										{col.title}
									</span>
									<span style={{ textAlign: 'right', minWidth: 0 }}>
										{value}
									</span>
								</div>
							);
						})}

						{actions.length > 0 && (
							<div
								style={{
									display: 'flex',
									flexWrap: 'wrap',
									gap: 8,
									marginTop: 10,
									paddingTop: 10,
									borderTop: '1px solid #f0f0f0',
								}}
							>
								{actions.map((col, ai) => (
									<div key={col.key ?? col.dataIndex ?? ai}>
										{cellValue(col, record, i)}
									</div>
								))}
							</div>
						)}
					</Card>
				);
			})}

			{pagination !== false && rows.length > pageSize && (
				<div style={{ textAlign: 'center', marginTop: 8 }}>
					<Pagination
						simple
						current={page}
						pageSize={pageSize}
						total={rows.length}
						onChange={setPage}
					/>
				</div>
			)}
		</div>
	);
};

const ResponsiveTable = (props) => {
	const isMobile = useIsMobile();

	if (!isMobile) return <Table {...props} />;

	const {
		columns = [],
		dataSource,
		rowKey,
		loading,
		pagination,
		rowSelection,
		locale,
	} = props;
	return (
		<MobileCards
			columns={columns}
			dataSource={dataSource}
			rowKey={rowKey}
			loading={loading}
			pagination={pagination}
			rowSelection={rowSelection}
			locale={locale}
		/>
	);
};

MobileCards.propTypes = {
	columns: PropTypes.array,
	dataSource: PropTypes.array,
	rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
	loading: PropTypes.bool,
	pagination: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
	rowSelection: PropTypes.object,
	locale: PropTypes.object,
};

ResponsiveTable.propTypes = {
	columns: PropTypes.array,
	dataSource: PropTypes.array,
	rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
	loading: PropTypes.bool,
	pagination: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
	rowSelection: PropTypes.object,
	locale: PropTypes.object,
};

export default ResponsiveTable;
