'use client';

import { useCallback } from 'react';

import { useRouter, useSearchParams } from 'next/navigation';

import { Download, FileIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';

import { deleteFile } from '@kit/module-builder/actions/file-actions';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import { useActionWithToast } from '@kit/ui/use-action-with-toast';

import { DeleteConfirmButton } from './delete-confirm-button';

interface FileRecord {
  id: string;
  file_name: string;
  original_name: string;
  mime_type: string;
  file_size: number;
  created_at: string;
  storage_path: string;
  publicUrl: string;
}

interface FilesTableProps {
  files: FileRecord[];
  pagination: { total: number; page: number; pageSize: number };
}

function formatFileSize(bytes: number): string {
  if (bytes >= 1024 * 1024) {
    return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
  }

  return `${(bytes / 1024).toFixed(1)} KB`;
}

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('de-AT', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function getMimeLabel(mimeType: string): string {
  const map: Record<string, string> = {
    'application/pdf': 'PDF',
    'image/jpeg': 'JPEG',
    'image/png': 'PNG',
    'image/gif': 'GIF',
    'image/webp': 'WebP',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
      'DOCX',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'XLSX',
    'text/csv': 'CSV',
    'text/plain': 'TXT',
    'application/zip': 'ZIP',
  };

  return map[mimeType] ?? mimeType.split('/').pop()?.toUpperCase() ?? 'Datei';
}

export function FilesTable({ files, pagination }: FilesTableProps) {
  const t = useTranslations('common');
  const router = useRouter();
  const searchParams = useSearchParams();
  const { total, page, pageSize } = pagination;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const { execute: executeDelete, isPending: isDeleting } = useActionWithToast(
    deleteFile,
    {
      successMessage: 'Datei gelöscht',
      onSuccess: () => router.refresh(),
    },
  );

  const handlePageChange = useCallback(
    (newPage: number) => {
      const params = new URLSearchParams(searchParams.toString());
      params.set('page', String(newPage));
      router.push(`?${params.toString()}`);
    },
    [router, searchParams],
  );

  return (
    <Card>
      <CardHeader>
        <CardTitle>Dateien ({total})</CardTitle>
      </CardHeader>
      <CardContent>
        {files.length === 0 ? (
          <div className="flex flex-col items-center justify-center rounded-lg border border-dashed p-12 text-center">
            <FileIcon className="text-muted-foreground mb-4 h-12 w-12" />
            <h3 className="text-lg font-semibold">Keine Dateien vorhanden</h3>
            <p className="text-muted-foreground mt-1 max-w-sm text-sm">
              Laden Sie Ihre erste Datei hoch.
            </p>
          </div>
        ) : (
          <div className="overflow-x-auto rounded-md border">
            <table className="w-full min-w-[640px] text-sm">
              <thead>
                <tr className="bg-muted/50 border-b">
                  <th scope="col" className="p-3 text-left font-medium">
                    Dateiname
                  </th>
                  <th scope="col" className="p-3 text-left font-medium">
                    Typ
                  </th>
                  <th scope="col" className="p-3 text-right font-medium">
                    Größe
                  </th>
                  <th scope="col" className="p-3 text-left font-medium">
                    Hochgeladen
                  </th>
                  <th scope="col" className="p-3 text-right font-medium">
                    Aktionen
                  </th>
                </tr>
              </thead>
              <tbody>
                {files.map((file) => (
                  <tr key={file.id} className="hover:bg-muted/30 border-b">
                    <td className="max-w-[300px] truncate p-3 font-medium">
                      {file.original_name}
                    </td>
                    <td className="p-3">
                      <Badge variant="secondary">
                        {getMimeLabel(file.mime_type)}
                      </Badge>
                    </td>
                    <td className="text-muted-foreground p-3 text-right">
                      {formatFileSize(file.file_size)}
                    </td>
                    <td className="text-muted-foreground p-3">
                      {formatDate(file.created_at)}
                    </td>
                    <td className="p-3 text-right">
                      <div className="flex items-center justify-end gap-1">
                        <a
                          href={file.publicUrl}
                          target="_blank"
                          rel="noopener noreferrer"
                          download={file.original_name}
                        >
                          <Button
                            variant="ghost"
                            size="sm"
                            data-test="file-download-btn"
                          >
                            <Download className="h-4 w-4" />
                          </Button>
                        </a>
                        <DeleteConfirmButton
                          title={t('deleteFile')}
                          description={t('deleteFileConfirm')}
                          isPending={isDeleting}
                          onConfirm={() => executeDelete({ fileId: file.id })}
                        />
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {totalPages > 1 && (
          <div className="mt-4 flex items-center justify-between">
            <p className="text-muted-foreground text-sm">
              Seite {page} von {totalPages} ({total} Einträge)
            </p>
            <div className="flex gap-2">
              <Button
                variant="outline"
                size="sm"
                disabled={page <= 1}
                onClick={() => handlePageChange(page - 1)}
                data-test="files-prev-page"
              >
                Zurück
              </Button>
              <Button
                variant="outline"
                size="sm"
                disabled={page >= totalPages}
                onClick={() => handlePageChange(page + 1)}
                data-test="files-next-page"
              >
                Weiter
              </Button>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}
