"use client";

import {
	RiAttachmentLine,
	RiFilePdf2Line,
	RiImageLine,
	RiUserLine,
	RiVerifiedBadgeFill,
} from "@remixicon/react";
import { useRouter } from "next/navigation";
import type React from "react";
import { useState, useTransition } from "react";
import { AttachmentGridItem } from "@/features/attachments/components/attachment-grid-item";
import { AttachmentPreview } from "@/features/attachments/components/attachment-preview";
import { useAttachmentUrl } from "@/features/attachments/hooks/use-attachment-url";
import type { AttachmentForPeriod } from "@/features/attachments/queries";
import { fetchTransactionByIdAction } from "@/features/transactions/actions/fetch-by-id";
import type { TransactionDialogOptions } from "@/features/transactions/actions/fetch-dialog-options";
import { fetchTransactionDialogOptionsAction } from "@/features/transactions/actions/fetch-dialog-options";
import { TransactionDetailsDialog } from "@/features/transactions/components/dialogs/transaction-details-dialog";
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
import { PayerSelectContent } from "@/features/transactions/components/select-items";
import type { TransactionItem } from "@/features/transactions/components/types";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Card, CardContent } from "@/shared/components/ui/card";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/shared/components/ui/select";
import { cn } from "@/shared/utils/ui";

type FilterType = "all" | "images" | "pdfs";

function AttachmentGridItemWithUrl({
	attachment,
	onClick,
	onDetails,
	isLoadingDetails,
}: {
	attachment: AttachmentForPeriod;
	onClick: () => void;
	onDetails: () => void;
	isLoadingDetails: boolean;
}) {
	const { url, containerRef } = useAttachmentUrl(attachment.attachmentId);
	return (
		<div ref={containerRef}>
			<AttachmentGridItem
				attachment={attachment}
				url={url ?? undefined}
				onClick={onClick}
				onDetails={onDetails}
				isLoadingDetails={isLoadingDetails}
			/>
		</div>
	);
}

const FILTERS: {
	value: FilterType;
	label: string;
	icon: React.ReactNode;
}[] = [
	{
		value: "all",
		label: "Todos",
		icon: <RiAttachmentLine className="size-3.5" />,
	},
	{
		value: "images",
		label: "Imagens",
		icon: <RiImageLine className="size-3.5 text-blue-500" />,
	},
	{
		value: "pdfs",
		label: "PDFs",
		icon: <RiFilePdf2Line className="size-3.5 text-red-500" />,
	},
];

interface AttachmentsPageProps {
	attachments: AttachmentForPeriod[];
	adminPayerId: string;
}

const ALL_PAYERS = "all";

export function AttachmentsPage({
	attachments,
	adminPayerId,
}: AttachmentsPageProps) {
	const router = useRouter();
	const [filter, setFilter] = useState<FilterType>("all");
	const [payerFilter, setPayerFilter] = useState(adminPayerId);
	const [selectedIndex, setSelectedIndex] = useState(-1);
	const [transactionDetails, setTransactionDetails] =
		useState<TransactionItem | null>(null);
	const [loadingTransactionId, setLoadingTransactionId] = useState<
		string | null
	>(null);
	const [isPending, startTransition] = useTransition();

	// Edit dialog state
	const [editOpen, setEditOpen] = useState(false);
	const [transactionToEdit, setTransactionToEdit] =
		useState<TransactionItem | null>(null);
	const [dialogOptions, setDialogOptions] =
		useState<TransactionDialogOptions | null>(null);

	const payerOptions = Array.from(
		new Map(
			attachments.map((attachment) => [
				attachment.payerId,
				{
					value: attachment.payerId,
					label: attachment.payerName,
					avatarUrl: attachment.payerAvatarUrl,
				},
			]),
		).values(),
	).sort((a, b) =>
		a.label.localeCompare(b.label, "pt-BR", { sensitivity: "base" }),
	);

	const payerAttachments = attachments.filter(
		(attachment) =>
			payerFilter === ALL_PAYERS || attachment.payerId === payerFilter,
	);
	const selectedPayer = payerOptions.find(
		(option) => option.value === payerFilter,
	);

	const filteredAttachments = payerAttachments.filter((a) => {
		if (filter === "images") return a.mimeType.startsWith("image/");
		if (filter === "pdfs") return a.mimeType === "application/pdf";
		return true;
	});

	const imageCount = payerAttachments.filter((a) =>
		a.mimeType.startsWith("image/"),
	).length;
	const pdfCount = payerAttachments.filter(
		(a) => a.mimeType === "application/pdf",
	).length;

	const counts: Record<FilterType, number> = {
		all: payerAttachments.length,
		images: imageCount,
		pdfs: pdfCount,
	};

	function handleSelect(attachment: AttachmentForPeriod) {
		const idx = filteredAttachments.findIndex(
			(a) =>
				a.attachmentId === attachment.attachmentId &&
				a.transactionId === attachment.transactionId,
		);
		setSelectedIndex(idx);
	}

	function handleDetails(transactionId: string) {
		setLoadingTransactionId(transactionId);
		startTransition(async () => {
			const transaction = await fetchTransactionByIdAction(transactionId);
			setLoadingTransactionId(null);
			if (transaction) setTransactionDetails(transaction);
		});
	}

	function handleEdit(transaction: TransactionItem) {
		setTransactionToEdit(transaction);
		startTransition(async () => {
			const options = await fetchTransactionDialogOptionsAction();
			setDialogOptions(options);
			setEditOpen(true);
		});
	}

	return (
		<div className="w-full space-y-6">
			<Card>
				<CardContent>
					{attachments.length === 0 ? (
						<div className="flex w-full items-center justify-center py-12">
							<EmptyState
								media={<RiAttachmentLine className="size-6 text-primary" />}
								title="Nenhum anexo neste mês"
								description="Adicione comprovantes nos seus lançamentos para vê-los aqui."
							/>
						</div>
					) : (
						<div className="space-y-4">
							{/* Header: filtros + contagem */}
							<div className="flex flex-wrap items-center justify-between gap-3">
								<p className="text-sm text-muted-foreground">
									{filteredAttachments.length}{" "}
									{filteredAttachments.length === 1 ? "anexo" : "anexos"}
									{filter !== "all" &&
										` · ${FILTERS.find((f) => f.value === filter)?.label.toLowerCase()}`}
								</p>
								<div className="flex w-full flex-wrap items-center justify-end gap-2 sm:w-auto">
									<Select
										value={payerFilter}
										onValueChange={(value) => {
											setPayerFilter(value);
											setSelectedIndex(-1);
										}}
									>
										<SelectTrigger
											size="sm"
											className="min-w-44 flex-1 sm:flex-none"
										>
											<SelectValue placeholder="Pessoa">
												{payerFilter === ALL_PAYERS ? (
													<span className="flex items-center gap-2">
														<RiUserLine className="size-4" />
														Todas as pessoas
													</span>
												) : selectedPayer ? (
													<span className="flex items-center gap-1.5">
														<PayerSelectContent
															label={selectedPayer.label}
															avatarUrl={selectedPayer.avatarUrl}
														/>
														{selectedPayer.value === adminPayerId && (
															<RiVerifiedBadgeFill
																className="size-4 text-blue-500"
																aria-label="Pessoa principal"
															/>
														)}
													</span>
												) : null}
											</SelectValue>
										</SelectTrigger>
										<SelectContent align="end">
											<SelectItem value={ALL_PAYERS}>
												<span className="flex items-center gap-2">
													<span className="flex size-6 items-center justify-center rounded-full bg-muted">
														<RiUserLine className="size-3.5" />
													</span>
													Todas as pessoas
												</span>
											</SelectItem>
											{payerOptions.map((option) => (
												<SelectItem key={option.value} value={option.value}>
													<span className="flex items-center gap-1.5">
														<PayerSelectContent
															label={option.label}
															avatarUrl={option.avatarUrl}
														/>
														{option.value === adminPayerId && (
															<RiVerifiedBadgeFill
																className="size-4 text-blue-500"
																aria-label="Pessoa principal"
															/>
														)}
													</span>
												</SelectItem>
											))}
										</SelectContent>
									</Select>
									<div className="flex items-center gap-1 rounded-lg border p-1">
										{FILTERS.map(({ value, label, icon }) => (
											<button
												key={value}
												type="button"
												onClick={() => {
													setFilter(value);
													setSelectedIndex(-1);
												}}
												className={cn(
													"flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
													filter === value
														? "bg-primary text-primary-foreground [&_svg]:opacity-100"
														: "text-muted-foreground hover:text-foreground",
												)}
											>
												<span className={cn(filter !== value && "opacity-60")}>
													{icon}
												</span>
												{label}{" "}
												<span
													className={cn(
														"tabular-nums",
														filter === value ? "opacity-80" : "opacity-60",
													)}
												>
													({counts[value]})
												</span>
											</button>
										))}
									</div>
								</div>
							</div>

							{filteredAttachments.length === 0 ? (
								<div className="flex w-full items-center justify-center py-12">
									<EmptyState
										media={<RiAttachmentLine className="size-6 text-primary" />}
										title="Nenhum anexo encontrado"
										description={
											payerAttachments.length === 0
												? "Não há anexos desta pessoa neste mês."
												: "Não há anexos do tipo selecionado neste mês."
										}
									/>
								</div>
							) : (
								<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
									{filteredAttachments.map((attachment) => (
										<AttachmentGridItemWithUrl
											key={`${attachment.attachmentId}-${attachment.transactionId}`}
											attachment={attachment}
											onClick={() => handleSelect(attachment)}
											onDetails={() => handleDetails(attachment.transactionId)}
											isLoadingDetails={
												isPending &&
												loadingTransactionId === attachment.transactionId
											}
										/>
									))}
								</div>
							)}
						</div>
					)}
				</CardContent>
			</Card>

			<AttachmentPreview
				attachments={filteredAttachments}
				selectedIndex={selectedIndex}
				onClose={() => setSelectedIndex(-1)}
			/>

			<TransactionDetailsDialog
				open={!!transactionDetails}
				onOpenChange={(open) => {
					if (!open) setTransactionDetails(null);
				}}
				transaction={transactionDetails}
				onEdit={handleEdit}
			/>

			{dialogOptions && transactionToEdit && (
				<TransactionDialog
					mode="update"
					open={editOpen}
					onOpenChange={(open) => {
						setEditOpen(open);
						if (!open) {
							setTransactionToEdit(null);
							setDialogOptions(null);
							router.refresh();
						}
					}}
					transaction={transactionToEdit}
					payerOptions={dialogOptions.payerOptions}
					splitPayerOptions={dialogOptions.splitPayerOptions}
					defaultPayerId={dialogOptions.defaultPayerId}
					accountOptions={dialogOptions.accountOptions}
					cardOptions={dialogOptions.cardOptions}
					categoryOptions={dialogOptions.categoryOptions}
					estabelecimentos={dialogOptions.estabelecimentos}
				/>
			)}
		</div>
	);
}
