"use client";

import { useMemo, useState, useTransition } from "react";
import { useRouter } from "next/navigation";

type PortalNotificationItem = {
  id: string;
  title: string;
  message: string;
  status: string;
  url: string | null;
  createdAt: Date | string;
  readAt: Date | string | null;
};

function statusLabel(value: string) {
  const labels: Record<string, string> = {
    PENDING: "Novo",
    SENT: "Poslato",
    READ: "Pročitano",
    FAILED: "Neuspešno",
    ARCHIVED: "Arhivirano",
  };

  return labels[value] || value;
}

function formatDate(value: Date | string) {
  return new Intl.DateTimeFormat("sr-Latn-RS", {
    day: "2-digit",
    month: "long",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    timeZone: "Europe/Belgrade",
  }).format(new Date(value));
}

export function PortalNotificationCenter({
  initialItems,
}: {
  initialItems: PortalNotificationItem[];
}) {
  const router = useRouter();
  const [items, setItems] = useState(initialItems);
  const [message, setMessage] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();

  const unreadCount = useMemo(
    () => items.filter((item) => item.status === "PENDING" || item.status === "SENT").length,
    [items],
  );

  function updateItems(nextItems: PortalNotificationItem[]) {
    setItems(nextItems);
    router.refresh();
  }

  async function persistNotificationState(ids?: string[], markAll = false) {
    const response = await fetch("/api/portal/notifications", {
      method: "POST",
      headers: {
        "content-type": "application/json",
      },
      body: JSON.stringify({
        ids,
        markAll,
      }),
    });

    const payload = (await response.json()) as {
      message?: string;
      items?: PortalNotificationItem[];
    };

    if (!response.ok) {
      throw new Error(payload.message || "Ažuriranje notifikacija nije uspelo.");
    }

    updateItems(payload.items ?? []);
  }

  function markNotifications(ids?: string[], markAll = false) {
    startTransition(async () => {
      try {
        await persistNotificationState(ids, markAll);
        setMessage(
          markAll
            ? "Sve notifikacije su označene kao pročitane."
            : "Notifikacija je označena kao pročitana.",
        );
      } catch (error) {
        setMessage(
          error instanceof Error
            ? error.message
            : "Ažuriranje notifikacija nije uspelo.",
        );
      }
    });
  }

  function openNotification(item: PortalNotificationItem) {
    const targetUrl = item.url;

    if (!targetUrl) {
      return;
    }

    startTransition(async () => {
      try {
        const isUnread = item.status === "PENDING" || item.status === "SENT";
        if (isUnread) {
          await persistNotificationState([item.id]);
        }
        setMessage(null);
        router.push(targetUrl);
      } catch (error) {
        setMessage(
          error instanceof Error
            ? error.message
            : "Otvaranje notifikacije nije uspelo.",
        );
      }
    });
  }

  return (
    <section id="notifikacije" className="partner-app-panel p-6">
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div>
          <p className="eyebrow">Notifikacije</p>
          <h2 className="mt-3 font-display text-3xl font-semibold text-foreground">
            Operativne i komercijalne poruke za vaš nalog
          </h2>
          <p className="mt-3 max-w-3xl text-sm leading-7 text-muted-foreground">
            Pregledajte nove poruke, otvorite relevantne detalje i označite ih kao pročitane kada završite sa akcijom.
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-3">
          <span className="admin-chip">Nepročitano: {unreadCount}</span>
          <button
            type="button"
            className="ghost-button"
            onClick={() => markNotifications(undefined, true)}
            disabled={isPending || unreadCount === 0}
          >
            Označi sve kao pročitano
          </button>
        </div>
      </div>

      {message ? (
        <div className="mt-5 rounded-[1.3rem] border border-primary/15 bg-primary/8 px-4 py-3 text-sm text-primary">
          {message}
        </div>
      ) : null}

      <div className="mt-5 grid gap-4 xl:grid-cols-2">
        {items.length ? (
          items.map((notification) => {
            const isUnread = notification.status === "PENDING" || notification.status === "SENT";

            return (
              <div key={notification.id} className="summary-item">
                <div className="flex flex-wrap gap-2">
                  <span className="admin-chip">{statusLabel(notification.status)}</span>
                  {isUnread ? <span className="admin-chip !text-primary">Novo</span> : null}
                </div>
                <div className="summary-item-value mt-3">{notification.title}</div>
                <p className="mt-3 text-sm leading-7 text-muted-foreground">{notification.message}</p>
                <p className="mt-4 text-xs uppercase tracking-[0.14em] text-muted-foreground">
                  {formatDate(notification.createdAt)}
                </p>
                {notification.readAt ? (
                  <p className="mt-2 text-xs uppercase tracking-[0.12em] text-muted-foreground">
                    Pročitano: {formatDate(notification.readAt)}
                  </p>
                ) : null}
                <div className="mt-4 flex flex-wrap gap-3">
                  {notification.url ? (
                    <button
                      type="button"
                      disabled={isPending}
                      className="ghost-button"
                      onClick={() => openNotification(notification)}
                    >
                      Otvori detalj
                    </button>
                  ) : null}
                  {isUnread ? (
                    <button
                      type="button"
                      className="primary-button"
                      onClick={() => markNotifications([notification.id])}
                      disabled={isPending}
                    >
                      Označi kao pročitano
                    </button>
                  ) : (
                    <span className="ghost-button">Pročitano</span>
                  )}
                </div>
              </div>
            );
          })
        ) : (
          <div className="summary-item text-sm leading-7 text-muted-foreground xl:col-span-2">
            Trenutno nema notifikacija za ovaj nalog.
          </div>
        )}
      </div>
    </section>
  );
}
