import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { useLoaderData, useFetcher, useNavigate, Link } from "react-router";
import { useState, useEffect } from "react";
import {
  getNotifications,
  getUnreadCount,
  markNotificationAsRead,
  markAllNotificationsAsRead,
} from "../services/notification.server";
import prisma from "../db.server";
import { FAIcon } from "../components/FAIcon";

import { getDefaultStoreDomainSync } from "../services/platform-settings.server";



export const loader = async ({ request }: LoaderFunctionArgs) => {
  const url = new URL(request.url);
  const shopDomain = url.searchParams.get("shop") || getDefaultStoreDomainSync();
  const page = parseInt(url.searchParams.get("page") || "1", 10);
  const filter = url.searchParams.get("filter") || "ALL"; // ALL or UNREAD

  let shopId: string | null = null;
  const shop = await prisma.shop.findUnique({
    where: { shopifyDomain: shopDomain.toLowerCase().trim() },
    select: { id: true },
  });
  if (shop) shopId = shop.id;

  try {
    const data = await getNotifications({
      shopId,
      page,
      pageSize: 20,
      isRead: filter === "UNREAD" ? false : undefined,
    });

    const unreadCount = await getUnreadCount(shopId);

    return {
      shopDomain,
      shopId,
      notifications: data.notifications.map((n) => ({
        id: n.id,
        type: n.type,
        title: n.title,
        message: n.message,
        isRead: n.isRead,
        readAt: n.readAt ? new Date(n.readAt).toISOString() : null,
        actionUrl: n.actionUrl,
        createdAt: new Date(n.createdAt).toISOString(),
      })),
      totalCount: data.totalCount,
      page: data.page,
      totalPages: data.totalPages,
      unreadCount,
      filter,
      error: null,
    };
  } catch (err: any) {
    return {
      shopDomain,
      shopId: null,
      notifications: [],
      totalCount: 0,
      page: 1,
      totalPages: 1,
      unreadCount: 0,
      filter: "ALL",
      error: err.message || "Failed to load notifications",
    };
  }
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const formData = await request.formData();
  const intent = String(formData.get("_intent") || "");
  const shopId = String(formData.get("shopId") || "");

  try {
    if (intent === "mark_read") {
      const notificationId = String(formData.get("notificationId") || "");
      if (notificationId) {
        await markNotificationAsRead(notificationId, shopId);
        return { success: true, intent };
      }
    }

    if (intent === "mark_all_read") {
      await markAllNotificationsAsRead(shopId);
      return { success: true, intent };
    }
  } catch (err: any) {
    return { success: false, error: err.message };
  }

  return null;
};

// Helper for formatting time ago
function formatTimeAgo(isoString: string): string {
  const date = new Date(isoString);
  const now = new Date();
  const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);

  if (seconds < 60) return "Just now";
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days} day${days === 1 ? "" : "s"} ago`;
  return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

// Icon mapper by notification type
function getNotificationIcon(type: string): { icon: string; color: string; bg: string } {
  switch (type) {
    case "SHOPIFY_SYNC_SUCCESS":
    case "SHOPIFY_CONNECTED":
      return { icon: "rotate", color: "#10B981", bg: "#ECFDF5" };
    case "SHOPIFY_SYNC_FAILED":
    case "SHOPIFY_DISCONNECTED":
      return { icon: "triangle-exclamation", color: "#EF4444", bg: "#FEF2F2" };
    case "AI_CONFIG_UPDATED":
      return { icon: "robot", color: "#4F46E5", bg: "#EEF2FF" };
    case "USAGE_LIMIT_WARNING":
    case "USAGE_LIMIT_REACHED":
      return { icon: "gauge-high", color: "#F59E0B", bg: "#FEF3C7" };
    case "SUBSCRIPTION_UPDATED":
      return { icon: "credit-card", color: "#8B5CF6", bg: "#F5F3FF" };
    default:
      return { icon: "bell", color: "#4F46E5", bg: "#EEF2FF" };
  }
}

export default function NotificationsPage() {
  const loaderData = useLoaderData<typeof loader>();
  const fetcher = useFetcher();
  const navigate = useNavigate();

  const [notifications, setNotifications] = useState(loaderData.notifications);
  const [unreadCount, setUnreadCount] = useState(loaderData.unreadCount);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    setNotifications(loaderData.notifications);
    setUnreadCount(loaderData.unreadCount);
  }, [loaderData]);

  const handleMarkRead = (id: string, actionUrl?: string | null) => {
    // Optimistic UI update
    setNotifications((prev) =>
      prev.map((item) => (item.id === id ? { ...item, isRead: true } : item))
    );
    setUnreadCount((prev) => Math.max(0, prev - 1));

    fetcher.submit(
      { _intent: "mark_read", notificationId: id, shopId: loaderData.shopId || "" },
      { method: "post" }
    );

    if (actionUrl) {
      navigate(actionUrl);
    }
  };

  const handleMarkAllRead = () => {
    // Optimistic UI update
    setNotifications((prev) => prev.map((item) => ({ ...item, isRead: true })));
    setUnreadCount(0);

    fetcher.submit(
      { _intent: "mark_all_read", shopId: loaderData.shopId || "" },
      { method: "post" }
    );
  };

  const handleFilterChange = (newFilter: string) => {
    const url = new URL(window.location.href);
    url.searchParams.set("filter", newFilter);
    url.searchParams.set("page", "1");
    navigate(`${url.pathname}${url.search}`);
  };

  const handlePageChange = (newPage: number) => {
    const url = new URL(window.location.href);
    url.searchParams.set("page", String(newPage));
    navigate(`${url.pathname}${url.search}`);
  };

  return (
    <div style={{ maxWidth: "1000px", margin: "0 auto", padding: "24px 16px", fontFamily: "Inter, system-ui, -apple-system, sans-serif" }}>
      <style>{`
        * { box-sizing: border-box; }
        .notif-card { background: #FFFFFF; border-radius: 12px; border: 1px solid #E2E8F0; box-shadow: 0 1px 3px rgba(0,0,0,0.05); overflow: hidden; }
        .notif-header { padding: 24px 28px; border-bottom: 1px solid #F1F5F9; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; }
        .notif-item { display: flex; gap: 16px; padding: 18px 24px; border-bottom: 1px solid #F1F5F9; transition: background 0.15s ease; cursor: pointer; position: relative; }
        .notif-item:hover { background-color: #F8FAFC; }
        .notif-item.unread { background-color: #F0F7FF; }
        .notif-item.unread:hover { background-color: #E6F0FA; }
        .notif-icon { width: 42px; height: 42px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
        .btn-primary { background: #4F46E5; color: #FFFFFF; font-weight: 600; padding: 8px 16px; border-radius: 8px; border: none; cursor: pointer; font-size: 13px; transition: background 0.15s ease; }
        .btn-primary:hover { background: #4338CA; }
        .btn-secondary { background: #FFFFFF; color: #475569; border: 1px solid #CBD5E1; font-weight: 600; padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 13px; transition: all 0.15s ease; }
        .btn-secondary:hover { background: #F8FAFC; border-color: #94A3B8; }
        .tab-btn { background: none; border: none; padding: 8px 14px; font-weight: 600; font-size: 13px; color: #64748B; cursor: pointer; border-radius: 6px; }
        .tab-btn.active { background: #EEF2FF; color: #4F46E5; }
      `}</style>

      {/* HEADER SECTION */}
      <div style={{ marginBottom: "24px" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: "12px", marginBottom: "8px" }}>
          <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
            <h1 style={{ fontSize: "24px", fontWeight: 800, color: "#0F172A", margin: 0, letterSpacing: "-0.5px" }}>
              Notifications
            </h1>
            {unreadCount > 0 && (
              <span style={{ backgroundColor: "#EF4444", color: "#FFFFFF", fontSize: "12px", fontWeight: 800, padding: "2px 8px", borderRadius: "12px" }}>
                {unreadCount} unread
              </span>
            )}
          </div>
          {unreadCount > 0 && (
            <button type="button" className="btn-secondary" onClick={handleMarkAllRead}>
              <FAIcon name="check-double" style={{ marginRight: "6px" }} /> Mark all as read
            </button>
          )}
        </div>
        <p style={{ color: "#64748B", fontSize: "14px", margin: 0 }}>
          View system alerts, account updates, and important activity.
        </p>
      </div>

      {/* ERROR STATE */}
      {loaderData.error && (
        <div style={{ padding: "16px", borderRadius: "8px", backgroundColor: "#FEE2E2", border: "1px solid #FCA5A5", color: "#991B1B", marginBottom: "20px", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <div>
            <strong>Unable to load notifications.</strong>
            <div style={{ fontSize: "13px" }}>{loaderData.error}</div>
          </div>
          <button type="button" className="btn-secondary" onClick={() => window.location.reload()}>
            Retry
          </button>
        </div>
      )}

      {/* MAIN CONTAINER */}
      <div className="notif-card">
        {/* TABS & FILTER BAR */}
        <div className="notif-header">
          <div style={{ display: "flex", gap: "4px" }}>
            <button
              type="button"
              className={`tab-btn ${loaderData.filter === "ALL" ? "active" : ""}`}
              onClick={() => handleFilterChange("ALL")}
            >
              All Notifications ({loaderData.totalCount})
            </button>
            <button
              type="button"
              className={`tab-btn ${loaderData.filter === "UNREAD" ? "active" : ""}`}
              onClick={() => handleFilterChange("UNREAD")}
            >
              Unread ({unreadCount})
            </button>
          </div>
          <span style={{ fontSize: "12px", color: "#94A3B8" }}>
            Showing {notifications.length} of {loaderData.totalCount}
          </span>
        </div>

        {/* NOTIFICATION LIST */}
        {notifications.length === 0 ? (
          /* EMPTY STATE */
          <div style={{ padding: "60px 24px", textAlign: "center" }}>
            <div style={{ width: "64px", height: "64px", borderRadius: "50%", backgroundColor: "#F1F5F9", color: "#94A3B8", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto 16px auto", fontSize: "24px" }}>
              <FAIcon name="bell-slash" />
            </div>
            <h3 style={{ fontSize: "16px", fontWeight: 700, color: "#1E293B", marginBottom: "6px" }}>
              No notifications
            </h3>
            <p style={{ color: "#64748B", fontSize: "14px", maxWidth: "400px", margin: "0 auto" }}>
              You're all caught up. New system updates and important alerts will appear here.
            </p>
          </div>
        ) : (
          <div>
            {notifications.map((n) => {
              const iconStyle = getNotificationIcon(n.type);
              return (
                <div
                  key={n.id}
                  className={`notif-item ${!n.isRead ? "unread" : ""}`}
                  onClick={() => handleMarkRead(n.id, n.actionUrl)}
                >
                  <div className="notif-icon" style={{ backgroundColor: iconStyle.bg, color: iconStyle.color }}>
                    <FAIcon name={iconStyle.icon} />
                  </div>
                  <div style={{ flex: 1 }}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: "4px" }}>
                      <h4 style={{ fontSize: "14px", fontWeight: n.isRead ? 600 : 800, color: "#0F172A", margin: 0 }}>
                        {n.title}
                        {!n.isRead && (
                          <span style={{ display: "inline-block", width: "8px", height: "8px", backgroundColor: "#4F46E5", borderRadius: "50%", marginLeft: "8px" }} />
                        )}
                      </h4>
                      <span style={{ fontSize: "12px", color: "#94A3B8", fontWeight: 500, flexShrink: 0, marginLeft: "12px" }}>
                        {formatTimeAgo(n.createdAt)}
                      </span>
                    </div>
                    <p style={{ fontSize: "13px", color: "#475569", margin: "0 0 8px 0", lineHeight: "1.4" }}>
                      {n.message}
                    </p>
                    {n.actionUrl && (
                      <span style={{ fontSize: "12px", color: "#4F46E5", fontWeight: 600, display: "inline-flex", alignItems: "center", gap: "4px" }}>
                        View details <FAIcon name="arrow-right" size="xs" />
                      </span>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}

        {/* PAGINATION BAR */}
        {loaderData.totalPages > 1 && (
          <div style={{ padding: "16px 24px", borderTop: "1px solid #F1F5F9", display: "flex", justifyContent: "space-between", alignItems: "center", backgroundColor: "#FAFAFA" }}>
            <span style={{ fontSize: "13px", color: "#64748B" }}>
              Page <strong>{loaderData.page}</strong> of <strong>{loaderData.totalPages}</strong>
            </span>
            <div style={{ display: "flex", gap: "8px" }}>
              <button
                type="button"
                className="btn-secondary"
                disabled={loaderData.page <= 1}
                onClick={() => handlePageChange(loaderData.page - 1)}
                style={{ opacity: loaderData.page <= 1 ? 0.5 : 1, cursor: loaderData.page <= 1 ? "not-allowed" : "pointer", display: "inline-flex", alignItems: "center", gap: "6px" }}
              >
                <FAIcon name="arrow-left" size="xs" /> Previous
              </button>
              <button
                type="button"
                className="btn-secondary"
                disabled={loaderData.page >= loaderData.totalPages}
                onClick={() => handlePageChange(loaderData.page + 1)}
                style={{ opacity: loaderData.page >= loaderData.totalPages ? 0.5 : 1, cursor: loaderData.page >= loaderData.totalPages ? "not-allowed" : "pointer", display: "inline-flex", alignItems: "center", gap: "6px" }}
              >
                Next <FAIcon name="arrow-right" size="xs" />
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
