'use client'

import { useMemo, useState, useEffect } from 'react';
import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, ColumnDef, SortingState, ColumnFiltersState } from '@tanstack/react-table';
import { useTranslations } from 'next-intl';
import { IconArrowUp, IconArrowDown, IconFilter, IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconEye } from '@/app/ui/icons/icons';
import { useQuery } from '@tanstack/react-query';
import { getViolationFilesArray } from '@/app/actions/violationActions';
import { useViewport } from '@/app/hooks/useViewport';
import { formatDate, formatDateTime } from '@/app/lib/formatDate';
import Link from 'next/link';
import DropDownList from '@/app/components/DropDownList';
import { useDebounce } from 'use-debounce';

interface FileViolation {
	createdAt: string;
	fileId: string;
	fileName: string;
	fileSize: number;
	latestViolationDate: string;
	mimeType: string;
	status: string;
	supportId: number;
	violationCount: number;
	countComplaint: number;
	countLawCase: number;
}

interface ViolationData {
	content: FileViolation[];
	totalPages: number;
	totalElements: number;
	size: number;
	number: number;
}

export default function ViolationsTable() {
	const t = useTranslations('Global');
	const viewport = useViewport();

	const [fileNameFilter, setFileNameFilter] = useState<string>('');
	const [dateFilter, setDateFilter] = useState<string>('all');
	const [pagination, setPagination] = useState({
		pageIndex: 0,
		pageSize: 10,
	});
	const [sorting, setSorting] = useState<SortingState>([]);
	const [debouncedFileName] = useDebounce(fileNameFilter, 500);

	const getDateRange = (filter: string): { start_date?: string; end_date?: string } => {
		const now = new Date();
		const end_date = formatDateTimeForAPI(now);

		switch (filter) {
			case 'today': {
				const start_date = formatDateTimeForAPI(new Date(now.setHours(0, 0, 0, 0)));
				return { start_date, end_date };
			}
			case 'week': {
				const weekAgo = new Date(now);
				weekAgo.setDate(weekAgo.getDate() - 7);
				weekAgo.setHours(0, 0, 0, 0);
				return { start_date: formatDateTimeForAPI(weekAgo), end_date };
			}
			case 'month': {
				const monthAgo = new Date(now);
				monthAgo.setMonth(monthAgo.getMonth() - 1);
				monthAgo.setHours(0, 0, 0, 0);
				return { start_date: formatDateTimeForAPI(monthAgo), end_date };
			}
			case 'older': {
				const monthAgo = new Date(now);
				monthAgo.setMonth(monthAgo.getMonth() - 1);
				monthAgo.setHours(0, 0, 0, 0);
				return { end_date: formatDateTimeForAPI(monthAgo) };
			}
			default:
				return {};
		}
	};

	const formatDateTimeForAPI = (date: Date): string => {
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		const hours = String(date.getHours()).padStart(2, '0');
		const minutes = String(date.getMinutes()).padStart(2, '0');
		const seconds = String(date.getSeconds()).padStart(2, '0');
		return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
	};

	const dateRange = getDateRange(dateFilter);

	const {
		data: violationData,
		isLoading,
		isFetching,
		isError,
		error,
		refetch,
	} = useQuery<ViolationData>({
		queryKey: ['violationData', pagination.pageIndex, pagination.pageSize, debouncedFileName, dateFilter],
		queryFn: () => getViolationFilesArray({
			page: pagination.pageIndex,
			size: pagination.pageSize,
			file_name: debouncedFileName || undefined,
			start_date: dateRange.start_date,
			end_date: dateRange.end_date,
		}),
		select: (data) => {
			console.log(data);
			return data;
		},
		placeholderData: (previousData) => previousData,
	});

	useEffect(() => {
		if (violationData) {
			setPagination(prev => ({
				...prev,
				pageIndex: violationData.number || 0,
			}));
		}
	}, [violationData]);

	const getMaxLengthByWidth = (): number => {
		if (viewport.device === 'MOBILE') return 26;
		if (viewport.device === 'TABLET') return 32;
		if (viewport.device === 'DESKTOP') return 84;
		return 100;
	};

	const cutFileName = (fileName: string) => {
		const MAX_FILE_NAME_LENGTH = getMaxLengthByWidth();
		const lastDotIndex = fileName.lastIndexOf('.');

		if (lastDotIndex <= 0) {
			return fileName.length > MAX_FILE_NAME_LENGTH ? fileName.substring(0, MAX_FILE_NAME_LENGTH - 3) + '...' : fileName;
		}

		const nameWithoutExtension = fileName.substring(0, lastDotIndex);
		const extension = fileName.substring(lastDotIndex);

		if (fileName.length <= MAX_FILE_NAME_LENGTH) {
			return fileName;
		}

		const maxNameLength = MAX_FILE_NAME_LENGTH - extension.length - 3;

		if (maxNameLength <= 0) {
			return '...';
		}

		return nameWithoutExtension.substring(0, maxNameLength) + '...';
	};

	const columns = useMemo<ColumnDef<FileViolation>[]>(
		() => [
			{
				accessorKey: 'supportId',
				header: ({ column }) => (
					<div className="column">
						<span>ID</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{column.getIsSorted() === 'asc' ? (
								<IconArrowUp />
							) : column.getIsSorted() === 'desc' ? (
								<IconArrowDown />
							) : (
								<IconFilter />
							)}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="text-center table-item table-item-id">
						{row.original.supportId}
					</div>
				),
			},
			{
				accessorKey: 'fileName',
				header: ({ column }) => (
					<div className="column start">
						<span>{t('file')}</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{column.getIsSorted() === 'asc' ? (
								<IconArrowUp />
							) : column.getIsSorted() === 'desc' ? (
								<IconArrowDown />
							) : (
								<IconFilter />
							)}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div
						className="flex items-center space-x-2 table-item table-item-file-name"
						title={row.original.fileName}
					>
						{cutFileName(row.original.fileName)}
					</div>
				),
			},
			{
				accessorKey: 'violationCount',
				header: ({ column }) => (
					<div className="column">
						<span>{t('matches')}</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{column.getIsSorted() === 'asc' ? (
								<IconArrowUp />
							) : column.getIsSorted() === 'desc' ? (
								<IconArrowDown />
							) : (
								<IconFilter />
							)}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="text-center table-item">
						{row.original.violationCount}
					</div>
				),
			},
			{
				accessorKey: 'countComplaint',
				header: ({ column }) => (
					<div className="column">
						<span>{t('complaint')}</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{column.getIsSorted() === 'asc' ? (
								<IconArrowUp />
							) : column.getIsSorted() === 'desc' ? (
								<IconArrowDown />
							) : (
								<IconFilter />
							)}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="text-center table-item">
						{row.original.countComplaint}
					</div>
				),
			},
			{
				accessorKey: 'countLawCase',
				header: ({ column }) => (
					<div className="column">
						<span>{t('claims')}</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{column.getIsSorted() === 'asc' ? (
								<IconArrowUp />
							) : column.getIsSorted() === 'desc' ? (
								<IconArrowDown />
							) : (
								<IconFilter />
							)}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="text-center table-item">
						{row.original.countLawCase}
					</div>
				),
			},
			{
				accessorKey: 'actions',
				header: () => (
					<div className="column">
						<span>{t('actions')}</span>
					</div>
				),
				cell: ({ row }) => (
					<div className="actions">
						<div className="actions-group">
							<Link
								href={`/pages/file/${row.original.fileId}`}
								className="bg-violet-500 hover:bg-violet-600"
								title={t('view')}
							>
								<IconEye />
							</Link>
						</div>
					</div>
				),
			},
		],
		[t, viewport]
	);

	const table = useReactTable({
		data: violationData?.content || [],
		columns,
		state: {
			sorting,
			pagination,
		},
		pageCount: violationData?.totalPages || -1,
		autoResetPageIndex: false,
		manualPagination: true, // Пагинация с бека
		manualSorting: false, // сортировка локально так как эндпоинт не поддерживает сортировку.
		manualFiltering: true, // Фильтрация с бека
		onPaginationChange: setPagination,
		onSortingChange: setSorting,
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getPaginationRowModel: getPaginationRowModel(),
	});

	const handleFileNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
		setFileNameFilter(e.target.value);
		setPagination(prev => ({ ...prev, pageIndex: 0 }));
	};

	const handleDateFilterChange = (value: string) => {
		setDateFilter(value);
		setPagination(prev => ({ ...prev, pageIndex: 0 }));
	};

	if (isError) {
		return <div className="block-wrapper">Error: {error?.message || t('error')}</div>;
	}

	return (
		<div className="block-wrapper">
			<div className="tab-content">
				<div className="tanstak-table-wrapper">
					<h3 className="tanstak-table-title">
						{t('matches-detected')}
					</h3>

					{/* Фильтры */}
					<div className="tanstak-table-filtres">
						<div className="table-filtres-wrapper">
							{/* Фильтр по дате */}
							<div className="table-filtres-item">
								<div className="table-filtres-label">{t('date-filter')}:</div>
								<DropDownList
									value={dateFilter}
									translatedValue={(() => {
										switch (dateFilter) {
											case 'all':
												return t('all-dates');
											case 'week':
												return t('for-a-week');
											case 'month':
												return t('for-a-month');
											case 'older':
												return t('older-than-a-month');
											default:
												return t('today');
										}
									})()}
									callBack={handleDateFilterChange}
								>
									<li value="all">{t('all-dates')}</li>
									<li value="today">{t('today')}</li>
									<li value="week">{t('for-a-week')}</li>
									<li value="month">{t('for-a-month')}</li>
									<li value="older">{t('older-than-a-month')}</li>
								</DropDownList>
							</div>

							{/* Фильтр по имени файла */}
							<div className="table-filtres-item">
								<div className="table-filtres-label">{t('file-name')}:</div>
								<input
									type="text"
									value={fileNameFilter}
									onChange={handleFileNameChange}
									placeholder={t('search')}
									className="table-filtres-text-filter"
								/>
							</div>
						</div>

						<div className="table-filtres-wrapper">
							<div className="table-filtres-item">
								<div className="table-filtres-label">{t('items-per-page')}:</div>
								<DropDownList
									value={table.getState().pagination.pageSize}
									//@ts-ignore
									callBack={(value: number) => {
										table.setPageSize(value);
										setPagination(prev => ({ ...prev, pageSize: value, pageIndex: 0 }));
									}}
								>
									{[5, 10, 20, 50, 100].map(pageSize => (
										<li key={pageSize} value={pageSize}>
											{t('show')} {pageSize}
										</li>
									))}
								</DropDownList>
							</div>
						</div>
					</div>

					{/* Таблица */}
					<div className="tanstak-table-block">
						<table className="tanstak-table">
							<thead className="tanstak-table-head">
								{table.getHeaderGroups().map(headerGroup => (
									<tr key={headerGroup.id}>
										{headerGroup.headers.map(header => (
											<th key={header.id}>
												{header.isPlaceholder
													? null
													: typeof header.column.columnDef.header === 'function'
														? header.column.columnDef.header(header.getContext())
														: (header.column.columnDef.header as string)}
											</th>
										))}
									</tr>
								))}
							</thead>
							<tbody className={`tanstak-table-body ${isFetching ? 'loading' : ''}`}>
								{isLoading && (
									<tr>
										<td colSpan={columns.length} className="text-center relative h-12.5">
											<div
												className="loading-animation"
											>
												<div
													className="global-spinner"
												>
												</div>
											</div>
										</td>
									</tr>
								)}
								{table.getRowModel().rows.length > 0 ? (
									table.getRowModel().rows.map(row => (
										<tr key={row.id}>
											{row.getVisibleCells().map(cell => (
												<td key={cell.id}>
													{typeof cell.column.columnDef.cell === 'function'
														? cell.column.columnDef.cell(cell.getContext())
														: (cell.getValue() as string)}
												</td>
											))}
										</tr>
									))
								) : (
									<tr>
										{!isLoading && (
											<td colSpan={columns.length} className="text-center">
												{t('no-data-for-selected-filters')}
											</td>
										)}
									</tr>
								)}
							</tbody>
						</table>
					</div>

					{/* Пагинация */}
					<div className="tanstak-table-pagination">
						<div className="pagination-info">
							<span className="pagination-info-pages">
								{t('page')}{' '}
								<strong>
									{table.getState().pagination.pageIndex + 1} {t('out-of')} {violationData?.totalPages || 1}
								</strong>
							</span>
							<span className="pagination-info-files">
								| {t('shown')} {violationData?.content?.length || 0} {t('out-of')} {violationData?.totalElements || 0}
							</span>
						</div>

						<div className="pagination-controls">
							<button
								className="arrow"
								onClick={() => table.firstPage()}
								disabled={!table.getCanPreviousPage()}
							>
								<IconDoubleArrowLeft />
							</button>
							<button
								className="arrow"
								onClick={() => table.previousPage()}
								disabled={!table.getCanPreviousPage()}
							>
								<IconArrowLeft />
							</button>

							<div className="pagination-controls-pages">
								{Array.from({ length: Math.min(5, violationData?.totalPages || 0) }, (_, i) => {
									const totalPages = violationData?.totalPages || 0;
									const currentPage = table.getState().pagination.pageIndex;
									let pageIndex = 0;

									if (totalPages <= 5) {
										pageIndex = i;
									} else if (currentPage <= 2) {
										pageIndex = i;
									} else if (currentPage >= totalPages - 3) {
										pageIndex = totalPages - 5 + i;
									} else {
										pageIndex = currentPage - 2 + i;
									}

									if (pageIndex < totalPages) {
										return (
											<button
												key={pageIndex}
												className={table.getState().pagination.pageIndex === pageIndex ? 'current' : 'other'}
												onClick={() => table.setPageIndex(pageIndex)}
											>
												{pageIndex + 1}
											</button>
										);
									}
									return null;
								})}
							</div>

							<button
								className="arrow"
								onClick={() => table.nextPage()}
								disabled={!table.getCanNextPage()}
							>
								<IconArrowRight />
							</button>
							<button
								className="arrow"
								onClick={() => table.lastPage()}
								disabled={!table.getCanNextPage()}
							>
								<IconDoubleArrowRight />
							</button>
						</div>
					</div>
				</div>
			</div>
		</div>
	);
}