'use client';

import { useState, useMemo, useEffect, ReactNode } from 'react';
import {
	useReactTable,
	getCoreRowModel,
	getSortedRowModel,
	getPaginationRowModel,
	getFilteredRowModel,
	ColumnDef,
	SortingState,
	ColumnFiltersState,
} from '@tanstack/react-table';
import { IconImageFile, IconVideoFile, IconAudioFile, IconEye, IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconArrowUp, IconArrowDown, IconFilter, IconFileOpen, IconShieldExclamation, IconDelete } from '@/app/ui/icons/icons';
import { useTranslations } from 'next-intl';
import DropDownList from '@/app/components/dropDownList';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { getUserFilesData, removeUserFile } from '@/app/actions/fileEntity';
import ModalWindow from '@/app/components/modalWindow';
import { toast } from 'sonner';

type FileType = 'image' | 'video' | 'audio';

type FileItem = {
	id: string;
	fileName: string;
	fileType: string;
	violations?: number | undefined;
	checks?: number | undefined;
	lastCheck?: number;
	_original?: ApiFile;
};

type ApiFile = {
	id: string;
	originalFileName: string;
	mimeType: string;
	violations: number;
	checks: number;
	updatedAt: string;
};

type ApiResponse = {
	files?: ApiFile[];
};

// Иконки для типов файлов
const FileTypeIcon = ({ type }: { type: string }) => {
	switch (type) {
		case 'image':
			return <span className="color-image">
				<IconImageFile />
			</span>;
		case 'video':
			return <span className="color-video">
				<IconVideoFile />
			</span>;
		case 'audio':
			return <span className="color-audio">
				<IconAudioFile />
			</span>;
		default:
			return <span>📄</span>;
	}
};

// Форматирование даты из timestamp
const formatDate = (timestamp: number) => {
	const date = new Date(timestamp);
	const day = date.getDate().toString().padStart(2, '0');
	const month = (date.getMonth() + 1).toString().padStart(2, '0');
	const year = date.getFullYear();

	return `${day}.${month}.${year}`;
};

const formatDateTime = (timestamp: number) => {
	const date = new Date(timestamp);
	const hours = date.getHours().toString().padStart(2, '0');
	const minutes = date.getMinutes().toString().padStart(2, '0');

	return `${hours}:${minutes}`;
};

export default function TanstakFilesTable({ fileType }: { fileType: string }) {
	const {
		data: tableData,
		isLoading,
		isError,
		error,
	} = useQuery<ApiResponse, Error, FileItem[], ['userFilesData']>({
		queryKey: ['userFilesData'],
		queryFn: getUserFilesData,

		select: (data: ApiResponse): FileItem[] => {
			if (!data?.files) return [];

			return data.files.map((item: ApiFile) => {
				const [datePart, timePart] = item.updatedAt.split(' ');
				const [day, month, year] = datePart.split('-').map(Number);
				const [hours, minutes, seconds] = timePart.split(':').map(Number);
				const newDate = new Date(year, month - 1, day, hours, minutes, seconds).getTime();

				return {
					id: item.id,
					fileName: item.originalFileName,
					fileType: item.mimeType.toLocaleLowerCase(),
					violations: item.violations,
					checks: item.checks,
					lastCheck: newDate,
					_original: item
				};
			});
		},
	});

	const queryClient = useQueryClient();

	// Состояния
	const [sorting, setSorting] = useState<SortingState>([]);
	const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
	const [dateFilter, setDateFilter] = useState<string>('all');
	const [typeFilter, setTypeFilter] = useState<string>(fileType);
	const [pagination, setPagination] = useState({
		pageIndex: 0,
		pageSize: 10,
	});
	const [openWindow, setOpenWindow] = useState<boolean>(false);
	const [openWindowChildren, setOpenWindowChildren] = useState<ReactNode>(null);

	const t = useTranslations("Global");

	// Определение колонок
	const columns = useMemo<ColumnDef<FileItem>[]>(
		() => [
			{
				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' ?
									<span>
										<IconArrowUp />
									</span>
									: column.getIsSorted() === 'desc' ?
										<span>
											<IconArrowDown />
										</span>
										: <span>
											<IconFilter />
										</span>
							}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="flex items-center space-x-2 w-[250px]">
						<FileTypeIcon type={row.original.fileType} />
						<div>
							<div className="font-medium w-full max-w-[250px] truncate" title={row.original.fileName}>{row.original.fileName}</div>
						</div>
					</div>
				),
				enableColumnFilter: false,
			},
			{
				accessorKey: 'status',
				header: ({ column }) => (
					<div className="column">
						<span>
							status
						</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{
								column.getIsSorted() === 'asc' ?
									<span>
										<IconArrowUp />
									</span>
									: column.getIsSorted() === 'desc' ?
										<span>
											<IconArrowDown />
										</span>
										: <span>
											<IconFilter />
										</span>
							}
						</button>
					</div>
				),
				cell: ({ row }) => {
					return (
						<div className={`text-center font-semibold`}>
							status
						</div>
					)
				},
			},
			{
				accessorKey: 'violations',
				header: ({ column }) => (
					<div className="column">
						<span>
							{t('violations')}
						</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{
								column.getIsSorted() === 'asc' ?
									<span>
										<IconArrowUp />
									</span>
									: column.getIsSorted() === 'desc' ?
										<span>
											<IconArrowDown />
										</span>
										: <span>
											<IconFilter />
										</span>
							}
						</button>
					</div>
				),
				cell: ({ row }) => {
					let classCollor = () => {
						let result = ''
						if (row.original.violations !== undefined) {
							result = row.original.violations > 0 ? 'text-red-600' : 'text-green-600'
						}
						return result;
					}
					return (
						<div className={`text-center font-semibold ${classCollor()}`}>
							{row.original.violations !== undefined ? row.original.violations : '-'}
						</div>
					)
				},
			},
			{
				accessorKey: 'checks',
				header: ({ column }) => (
					<div className="column">
						<span>
							{t('checks')}
						</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{
								column.getIsSorted() === 'asc' ?
									<span>
										<IconArrowUp />
									</span>
									: column.getIsSorted() === 'desc' ?
										<span>
											<IconArrowDown />
										</span>
										: <span>
											<IconFilter />
										</span>
							}
						</button>
					</div>
				),
				cell: ({ row }) => (
					<div className="text-center">
						{row.original.checks !== undefined ? row.original.checks : '-'}
					</div>
				),
			},
			{
				accessorKey: 'lastCheck',
				header: ({ column }) => (
					<div className="column">
						<span>
							{t('last-check')}
						</span>
						<button
							onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
							className="sort-button"
						>
							{
								column.getIsSorted() === 'asc' ?
									<span>
										<IconArrowUp />
									</span>
									: column.getIsSorted() === 'desc' ?
										<span>
											<IconArrowDown />
										</span>
										: <span>
											<IconFilter />
										</span>
							}
						</button>
					</div>
				),
				cell: ({ row }) => {
					return (
						<div className="text-center">
							{row.original.lastCheck ? (
								<>
									{formatDate(row.original.lastCheck)}
									<br />
									{formatDateTime(row.original.lastCheck)}
								</>
							) : (
								<div>-</div>
							)}
						</div>
					)
				},
				enableColumnFilter: false,
			},
			{
				id: 'actions',
				header: () => {
					return (
						<div className="column">
							{t('actions')}
						</div>
					)
				},
				cell: ({ row }) => (
					<div className="flex space-x-2 justify-center">
						<button
							onClick={() => handleView(row.original)}
							className="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 text-sm"
						>
							<IconEye />
						</button>
						<button
							onClick={() => handleDownload(row.original)}
							className="px-3 py-1 bg-green-500 text-white rounded hover:bg-green-600 text-sm"
						>
							<IconFileOpen />
						</button>
						<button
							onClick={() => handleProtect(row.original)}
							className="px-3 py-1 bg-violet-500 text-white rounded hover:bg-violet-600 text-sm"
						>
							<IconShieldExclamation />
						</button>
						<button
							onClick={() => handleOpenWindowForRemove(row.original)}
							className="px-3 py-1 bg-red-700 text-white rounded hover:bg-red-800 text-sm"
						>
							<IconDelete />
						</button>
					</div>
				),
				enableSorting: false,
				enableColumnFilter: false,
			},
		],
		[]
	);

	// Обработчики действий
	const handleView = (file: FileItem) => {
		console.log(`Просмотр файла: ${file.fileName}`);
	};

	const handleDownload = (file: FileItem) => {
		console.log(`Скачать: ${file.fileName}`);
	};

	const handleProtect = (file: FileItem) => {
		console.log(`Щиток: ${file.fileName}`);
	};

	const handleOpenWindowForRemove = async (file: FileItem) => {

		setOpenWindowChildren(() => {
			return (
				<div>
					<h3 className="text-2xl">
						{t('you-sure-you-want-to-delete')}
					</h3>
					<div className="mt-2 mb-8 text-center">{file.fileName}</div>
					<div className="flex justify-center gap-4">
						<button className="btn-primary btn-modal"
							onClick={() => {
								deleteMutation.mutate(file.id)
							}}
							disabled={deleteMutation.isPending}
						>
							{deleteMutation.isPending ? '...' : t('yes')}
						</button>
						<button className="btn-primary btn-modal"
							onClick={() => {
								setOpenWindow(false);
								setOpenWindowChildren(null);
							}}
						>
							{t('no')}
						</button>
					</div>
				</div>
			)
		})
		setOpenWindow(true);
	};

	const deleteMutation = useMutation({
		mutationFn: removeUserFile,

		onMutate: async (fileId: string) => {
			await queryClient.cancelQueries({ queryKey: ['userFilesData'] });

			queryClient.setQueryData<ApiResponse>(['userFilesData'], (old) => {
				if (!old?.files) return old;
				return {
					...old,
					files: old.files.filter(file => file.id !== fileId)
				};
			});
		},

		onError: () => {
			queryClient.invalidateQueries({ queryKey: ['userFilesData'] });
			toast.error(t('error'));
		},

		onSuccess: (response, fileId) => {
			if (response === fileId) {
				queryClient.invalidateQueries({
					queryKey: ['userFilesData'],
					refetchType: 'active'
				});

				setOpenWindow(false);
				setOpenWindowChildren(null);
				toast.success(t('file-has-been-deleted'));
			}
		},
	});

	// Фильтрация по типу файла и дате
	const filteredData = useMemo(() => {
		let result = tableData;
		if (!result) {
			return [];
		}

		// Фильтр по типу файла
		if (typeFilter !== 'all') {
			result = result.filter(item => item.fileType === typeFilter);
		}

		// Фильтр по дате
		if (dateFilter !== 'all') {
			const now = Date.now();
			const oneDay = 24 * 60 * 60 * 1000;
			const sevenDays = 7 * oneDay;
			const thirtyDays = 30 * oneDay;

			switch (dateFilter) {
				case 'today':
					const todayStart = new Date().setHours(0, 0, 0, 0);
					result = result.filter(item => {
						if (item.lastCheck) {
							return item.lastCheck >= todayStart
						} else {
							return 0
						}
					});
					break;
				case 'week':
					const weekAgo = now - sevenDays;
					result = result.filter(item => {
						if (item.lastCheck) {
							return item.lastCheck >= weekAgo;
						}
					});
					break;
				case 'month':
					const monthAgo = now - thirtyDays;
					result = result.filter(item => {
						if (item.lastCheck) {
							return item.lastCheck >= monthAgo;
						}
					});
					break;
				case 'older':
					const monthAgo2 = now - thirtyDays;
					result = result.filter(item => {
						if (item.lastCheck) {
							return item.lastCheck < monthAgo2;
						}
					});
					break;
			}
		}

		return result;
	}, [tableData, typeFilter, dateFilter]);

	useEffect(() => {
		const currentPageRows = table.getRowModel().rows;
		const pageCount = table.getPageCount();

		if (currentPageRows.length === 0 && pagination.pageIndex > 0 && pageCount > 0) {
			table.setPageIndex(pagination.pageIndex - 1);
		}
	}, [filteredData, pagination.pageIndex]);

	// Создание таблицы
	const table = useReactTable({
		data: filteredData,
		columns,
		state: {
			sorting,
			columnFilters,
			pagination
		},
		autoResetPageIndex: false,
		onPaginationChange: setPagination,
		onSortingChange: setSorting,
		onColumnFiltersChange: setColumnFilters,
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getPaginationRowModel: getPaginationRowModel(),
		getFilteredRowModel: getFilteredRowModel(),
		initialState: {
			pagination: {
				pageSize: 10,
			},
		},
	});

	return (
		<div className="tanstak-table-wrapper">
			<ModalWindow children={openWindowChildren} state={openWindow} callBack={setOpenWindow}></ModalWindow>
			{/* Фильтры */}
			<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={setDateFilter}
						>
							<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>

					{fileType === "all" && (
						<div className="table-filtres-item">
							<div className="table-filtres-label">{t('type-filter')}:</div>
							<DropDownList
								value={typeFilter}
								translatedValue={
									(() => {
										switch (typeFilter) {
											case 'image':
												return t('images')
											case 'video':
												return t('videos')
											case 'audio':
												return t('audios')
											default:
												return t('all-types')
										}
									})()
								}
								callBack={setTypeFilter}
							>
								<li value="all">
									{t('all-types')}
								</li>
								<li value="image">
									{t('images')}
								</li>
								<li value="video">
									{t('videos')}
								</li>
								<li value="audio">
									{t('audios')}
								</li>
							</DropDownList>
						</div>
					)}
				</div>

				<div className="table-filtres-item">
					<div className="table-filtres-label">{t('items-per-page')}:</div>
					<DropDownList
						value={table.getState().pagination.pageSize}
						//@ts-ignore сделал так потому что для table.setPageSize нужна цифра
						callBack={table.setPageSize}
					>
						{[5, 10, 20, 50, 100].map(pageSize => (
							<li key={pageSize} value={pageSize}>
								{t('show')} {pageSize}
							</li>
						))}
					</DropDownList>
				</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">
						{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>
								<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')} {table.getPageCount() ? table.getPageCount() : 1}
						</strong>
					</span>
					<span className="pagination-info-files">
						| {t('shown')} {table.getRowModel().rows.length} {t('out-of')} {filteredData.length} {t('files')}
					</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, table.getPageCount()) }, (_, i) => {
							const pageIndex = Math.max(
								0,
								Math.min(
									table.getPageCount() - 5,
									table.getState().pagination.pageIndex - 2
								)
							) + i;

							if (pageIndex < table.getPageCount()) {
								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>
	);
}