'use client';

import { useCallback, useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import { useRouter } from '@/i18n/navigation';
import { notificationsApi } from '@/lib/api/notifications';
import { useRealtime } from '@/lib/realtime/RealtimeProvider';
import { Button } from '@/components/ui/shared/Button';
import { NotificationCard } from '@/components/ui/notifications/NotificationCard';
import { getUserFacingError } from '@/components/shared/formatApiError';
import { useToast } from '@/lib/hooks/useToast';
import type { UserNotificationItem } from '@/types/notifications';

export function NotificationsPage() {
  const t = useTranslations('notifications');
  const tErrors = useTranslations('errors');
  const router = useRouter();
  const toast = useToast();
  const { lastNotification, setUnreadCount } = useRealtime();
  const [items, setItems] = useState<UserNotificationItem[]>([]);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);

  const loadPage = useCallback(async (cursor?: string | null, append = false) => {
    if (append) setLoadingMore(true);
    else setLoading(true);
    try {
      const res = await notificationsApi.listInbox({
        limit: 20,
        cursor: cursor ?? undefined,
      });
      setItems((prev) => (append ? [...prev, ...res.data.items] : res.data.items));
      setNextCursor(res.data.nextCursor);
    } catch (error: unknown) {
      toast.showError(getUserFacingError(error, tErrors, t('errorLoad')));
    } finally {
      setLoading(false);
      setLoadingMore(false);
    }
  }, [t, tErrors, toast]);

  useEffect(() => {
    void loadPage();
  }, [loadPage]);

  useEffect(() => {
    if (!lastNotification) return;
    setItems((prev) => {
      if (prev.some((item) => item.id === lastNotification.id)) return prev;
      return [lastNotification, ...prev];
    });
  }, [lastNotification]);

  const handleSelect = async (item: UserNotificationItem) => {
    try {
      if (!item.readAt) {
        await notificationsApi.markInboxRead(item.id);
        setItems((prev) =>
          prev.map((row) =>
            row.id === item.id ? { ...row, readAt: new Date().toISOString() } : row,
          ),
        );
        const countRes = await notificationsApi.inboxUnreadCount();
        setUnreadCount(countRes.data.count);
      }
    } catch {
      /* still navigate */
    }
    router.push(item.href);
  };

  const handleMarkAll = async () => {
    try {
      await notificationsApi.markInboxReadAll();
      setItems((prev) =>
        prev.map((row) => ({ ...row, readAt: row.readAt ?? new Date().toISOString() })),
      );
      setUnreadCount(0);
    } catch (error: unknown) {
      toast.showError(getUserFacingError(error, tErrors, t('errorMarkRead')));
    }
  };

  return (
    <div className="space-y-4 w-full">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div className="min-w-0">
          <h1 className="text-xl sm:text-2xl font-semibold text-text-primary">{t('pageTitle')}</h1>
          <p className="text-sm text-text-muted mt-1">{t('pageSubtitle')}</p>
        </div>
        <Button
          variant="outline"
          size="sm"
          className="w-full sm:w-auto shrink-0"
          onClick={() => void handleMarkAll()}
        >
          {t('markAllRead')}
        </Button>
      </div>

      <div className="space-y-2 w-full">
        {loading ? (
          <p className="text-sm text-text-muted">{t('loading')}</p>
        ) : items.length === 0 ? (
          <p className="text-sm text-text-muted surface-card p-4">{t('empty')}</p>
        ) : (
          items.map((item) => (
            <NotificationCard key={item.id} item={item} onSelect={(row) => void handleSelect(row)} />
          ))
        )}
      </div>

      {nextCursor ? (
        <Button
          variant="outline"
          size="sm"
          className="w-full sm:w-auto"
          isLoading={loadingMore}
          onClick={() => void loadPage(nextCursor, true)}
        >
          {t('loadMore')}
        </Button>
      ) : null}
    </div>
  );
}
