import { useCallback, useEffect, useState } from "react";
import { getConfig, getPreview, type Preview, putConfig } from "../api.js";
import { Badge, Button, Card, useToast } from "../components.js";
import { platformOf } from "../hooks.js";

export const Games = () => {
	const [preview, setPreview] = useState<Preview>();
	const [loading, setLoading] = useState(false);
	const [showSkipped, setShowSkipped] = useState(false);
	const toast = useToast();

	const refresh = useCallback(() => {
		setLoading(true);
		getPreview()
			.then(setPreview)
			.catch((e) => toast(String(e)))
			.finally(() => setLoading(false));
	}, [toast]);
	useEffect(refresh, [refresh]);

	// Toggle a title's exclude override, persist, and refresh the preview.
	const setExcluded = async (externalId: string, exclude: boolean) => {
		const config = await getConfig();
		const overrides = { ...config.gameOverrides };
		const current = overrides[externalId] ?? {};
		if (exclude) overrides[externalId] = { ...current, exclude: true };
		else {
			const { exclude: _drop, ...rest } = current;
			if (Object.keys(rest).length) overrides[externalId] = rest;
			else delete overrides[externalId];
		}
		await putConfig({ ...config, gameOverrides: overrides });
		toast(exclude ? "Excluded" : "Included");
		refresh();
	};

	if (!preview) return <Card>{loading ? "Scanning…" : "Loading…"}</Card>;

	const { entries, report } = preview;
	const excluded = report.excluded ?? [];

	return (
		<>
			<Card
				title={`Games (${entries.length})`}
				hint="What will be reconciled into the library. Untick a title to exclude it; covers come from your art provider."
				right={
					<Button disabled={loading} onClick={refresh}>
						{loading ? "Scanning…" : "Rescan"}
					</Button>
				}
			>
				{entries.length === 0 && excluded.length === 0 ? (
					<div className="empty-state">
						No games found. Add ROM roots in <strong>Setup</strong>, then
						rescan.
					</div>
				) : (
					<div className="scroll">
						<table>
							<thead>
								<tr>
									<th style={{ width: 52 }} />
									<th>Title</th>
									<th style={{ width: 90 }}>Platform</th>
									<th>Launch command</th>
									<th style={{ width: 60 }}>Include</th>
								</tr>
							</thead>
							<tbody>
								{entries.map((e) => (
									<tr key={e.external_id}>
										<td>
											{e.art?.portrait ? (
												<img
													className="cover"
													src={e.art.portrait}
													alt={`${e.title} cover`}
													loading="lazy"
												/>
											) : (
												<span className="cover empty" />
											)}
										</td>
										<td>{e.title}</td>
										<td>
											<Badge>{platformOf(e.external_id)}</Badge>
										</td>
										<td className="mono" title={e.launch?.value}>
											{truncate(e.launch?.value ?? "", 70)}
										</td>
										<td>
											<input
												type="checkbox"
												checked
												onChange={() => setExcluded(e.external_id, true)}
											/>
										</td>
									</tr>
								))}
								{excluded.map((x) => (
									<tr key={x.external_id} style={{ opacity: 0.55 }}>
										<td>
											<span className="cover empty" />
										</td>
										<td>{x.title}</td>
										<td>
											<Badge>{platformOf(x.external_id)}</Badge>
										</td>
										<td className="subtle">excluded</td>
										<td>
											<input
												type="checkbox"
												checked={false}
												onChange={() => setExcluded(x.external_id, false)}
											/>
										</td>
									</tr>
								))}
							</tbody>
						</table>
					</div>
				)}
			</Card>

			{report.skipped.length > 0 && (
				<Card
					title={`Skipped (${report.skipped.length})`}
					right={
						<Button onClick={() => setShowSkipped((s) => !s)}>
							{showSkipped ? "Hide" : "Show"}
						</Button>
					}
				>
					{showSkipped && (
						<div className="scroll">
							<table>
								<tbody>
									{report.skipped.map((s) => (
										<tr key={s.external_id}>
											<td>{s.title}</td>
											<td className="subtle">{s.reason}</td>
										</tr>
									))}
								</tbody>
							</table>
						</div>
					)}
				</Card>
			)}
		</>
	);
};

const truncate = (s: string, n: number): string =>
	s.length > n ? `${s.slice(0, n)}…` : s;
