import { useState, useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "wouter";
import {
  useListApps,
  getListAppsQueryKey,
  useGetHomeStats,
  getGetHomeStatsQueryKey,
  useListNotifications,
  getListNotificationsQueryKey,
  useLogout,
  useUpdateLanguage,
  useUpdateMyAppOrder,
  getGetMeQueryKey,
  type App,
} from "@workspace/api-client-react";
import { useQueryClient } from "@tanstack/react-query";
import { useAuth } from "@/contexts/AuthContext";
import { Bell, LogOut, Globe } from "lucide-react";
import * as LucideIcons from "lucide-react";
import i18n from "@/i18n";
import {
  DndContext,
  PointerSensor,
  TouchSensor,
  useSensor,
  useSensors,
  closestCenter,
  type DragEndEvent,
} from "@dnd-kit/core";
import {
  SortableContext,
  arrayMove,
  rectSortingStrategy,
  useSortable,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

function gradientForColor(color: string): string {
  const c = (color ?? "").toLowerCase();
  if (c.includes("a855f7") || c.includes("8b5cf6") || c.includes("purple") || c.includes("violet")) return "icon-tile-purple";
  if (c.includes("10b981") || c.includes("22c55e") || c.includes("green") || c.includes("emerald")) return "icon-tile-green";
  if (c.includes("f59e0b") || c.includes("f97316") || c.includes("orange") || c.includes("amber")) return "icon-tile-orange";
  if (c.includes("ec4899") || c.includes("pink") || c.includes("rose")) return "icon-tile-pink";
  if (c.includes("14b8a6") || c.includes("06b6d4") || c.includes("teal") || c.includes("cyan")) return "icon-tile-teal";
  return "icon-tile-blue";
}

function AppIcon({ app, onClick }: { app: { nameAr: string; nameEn: string; iconName: string; color: string; route: string }; onClick: () => void }) {
  const { i18n: i18nInstance } = useTranslation();
  const lang = i18nInstance.language;
  const name = lang === "ar" ? app.nameAr : app.nameEn;

  const Icon = (LucideIcons as unknown as Record<string, React.ComponentType<{ size?: number; color?: string }>>)[app.iconName]
    ?? LucideIcons.Grid2X2;

  return (
    <button
      onClick={onClick}
      className="flex flex-col items-center gap-2 group"
    >
      <div className={`icon-tile w-16 h-16 ${gradientForColor(app.color)} group-hover:scale-105`}>
        <Icon size={28} color="#FFFFFF" />
      </div>
      <span className="text-xs text-foreground/80 font-medium text-center leading-tight max-w-16 truncate">
        {name}
      </span>
    </button>
  );
}

function SortableAppIcon({ app, onClick }: { app: App; onClick: () => void }) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: app.id });
  const style: React.CSSProperties = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.6 : 1,
    zIndex: isDragging ? 20 : "auto",
    touchAction: "none",
  };
  return (
    <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
      <AppIcon app={app} onClick={onClick} />
    </div>
  );
}

export default function HomePage() {
  const { t, i18n: i18nInstance } = useTranslation();
  const [, setLocation] = useLocation();
  const { user } = useAuth();
  const queryClient = useQueryClient();
  const [time, setTime] = useState(new Date());
  const lang = i18nInstance.language;

  const { data: apps } = useListApps({ query: { queryKey: getListAppsQueryKey() } });
  const updateOrder = useUpdateMyAppOrder();
  const [orderedApps, setOrderedApps] = useState<App[] | null>(null);

  useEffect(() => {
    if (!apps) return;
    setOrderedApps((prev) => {
      if (!prev) return apps;
      const byId = new Map(apps.map((a) => [a.id, a]));
      const kept = prev
        .map((a) => byId.get(a.id))
        .filter((a): a is App => a !== undefined);
      const keptIds = new Set(kept.map((a) => a.id));
      const added = apps.filter((a) => !keptIds.has(a.id));
      return [...kept, ...added];
    });
  }, [apps]);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
    useSensor(TouchSensor, { activationConstraint: { delay: 250, tolerance: 5 } }),
  );

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id || !orderedApps) return;
    const oldIndex = orderedApps.findIndex((a) => a.id === active.id);
    const newIndex = orderedApps.findIndex((a) => a.id === over.id);
    if (oldIndex < 0 || newIndex < 0) return;
    const previous = orderedApps;
    const next = arrayMove(orderedApps, oldIndex, newIndex);
    setOrderedApps(next);
    updateOrder.mutate(
      { data: { order: next.map((a) => a.id) } },
      {
        onSuccess: (data) => {
          setOrderedApps(data);
          queryClient.setQueryData(getListAppsQueryKey(), data);
        },
        onError: () => {
          setOrderedApps(previous);
          queryClient.invalidateQueries({ queryKey: getListAppsQueryKey() });
        },
      },
    );
  };

  const sortableIds = useMemo(() => (orderedApps ?? []).map((a) => a.id), [orderedApps]);
  const { data: stats } = useGetHomeStats({ query: { queryKey: getGetHomeStatsQueryKey() } });
  const { data: notifications } = useListNotifications({ query: { queryKey: getListNotificationsQueryKey() } });

  const logout = useLogout();
  const updateLanguage = useUpdateLanguage();

  useEffect(() => {
    const timer = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(timer);
  }, []);

  const dateLocale = lang === "ar" ? "ar-SA" : "en-US";
  const dayName = new Intl.DateTimeFormat(dateLocale, { weekday: "long" }).format(time);
  const hijriDate = new Intl.DateTimeFormat(
    lang === "ar" ? "ar-SA-u-ca-islamic-umalqura" : "en-US-u-ca-islamic-umalqura",
    { day: "numeric", month: "long", year: "numeric" },
  ).format(time);
  const gregorianDate = new Intl.DateTimeFormat(
    lang === "ar" ? "ar-SA-u-ca-gregory" : "en-US",
    { day: "numeric", month: "long", year: "numeric" },
  ).format(time);

  const unreadCount = notifications?.filter((n) => !n.isRead).length ?? stats?.unreadNotifications ?? 0;

  const displayName = lang === "ar"
    ? (user?.displayNameAr ?? user?.username)
    : (user?.displayNameEn ?? user?.username);

  const isAdmin = user?.roles?.includes("admin") ?? false;

  const handleLogout = () => {
    logout.mutate(undefined, {
      onSuccess: () => {
        queryClient.clear();
        setLocation("/login");
      },
    });
  };

  const toggleLanguage = () => {
    const newLang = lang === "ar" ? "en" : "ar";
    i18n.changeLanguage(newLang);
    updateLanguage.mutate(
      { data: { language: newLang } },
      { onSuccess: () => queryClient.invalidateQueries({ queryKey: getGetMeQueryKey() }) },
    );
  };

  const dockApps = (orderedApps ?? apps)?.filter((a) => ["services", "chat", "notifications", "admin"].includes(a.slug)) ?? [];

  return (
    <div className="min-h-screen os-bg flex flex-col overflow-hidden relative">
      {/* Status Bar */}
      <div className="topbar-glass px-4 py-3 flex items-center justify-between gap-2 z-10 sticky top-0">
        <div className="flex items-center gap-3 min-w-0 shrink">
          <span className="text-foreground font-medium text-sm truncate max-w-24">{displayName}</span>
        </div>

        <div className="flex flex-col items-center text-foreground leading-tight min-w-0 px-2">
          <div className="font-mono text-sm font-bold">
            {time.toLocaleTimeString(dateLocale, {
              hour: "2-digit",
              minute: "2-digit",
            })}
          </div>
          <div className="text-[10px] text-muted-foreground flex items-center gap-1 mt-0.5 max-w-full truncate">
            <span className="truncate">{dayName}</span>
            <span aria-hidden="true">·</span>
            <span className="truncate">{hijriDate}</span>
          </div>
          <div className="text-[10px] text-muted-foreground max-w-full truncate">
            {gregorianDate}
          </div>
        </div>

        <div className="flex items-center gap-2">
          <button
            onClick={toggleLanguage}
            className="text-muted-foreground hover:text-foreground transition-colors text-xs font-medium px-2 py-1 rounded-lg hover:bg-slate-100"
          >
            {t("common.language")}
          </button>
          <button
            onClick={() => setLocation("/notifications")}
            className="relative p-1.5 rounded-lg hover:bg-slate-100 text-muted-foreground hover:text-foreground transition-colors"
          >
            <Bell size={18} />
            {unreadCount > 0 && (
              <span className="absolute -top-1 -right-1 bg-destructive text-destructive-foreground text-xs rounded-full w-4 h-4 flex items-center justify-center font-bold">
                {unreadCount > 9 ? "9+" : unreadCount}
              </span>
            )}
          </button>
          <button
            onClick={handleLogout}
            className="p-1.5 rounded-lg hover:bg-slate-100 text-muted-foreground hover:text-foreground transition-colors"
          >
            <LogOut size={18} />
          </button>
        </div>
      </div>

      {/* Main Content */}
      <div className="flex-1 p-6 pb-28 overflow-y-auto">
        {/* Stats Row — admin only */}
        {isAdmin && stats && (
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-8">
            <div className="glass-panel rounded-2xl p-3 text-center">
              <div className="text-2xl font-bold text-primary">{stats.totalApps}</div>
              <div className="text-xs text-muted-foreground mt-1">{t("home.myApps")}</div>
            </div>
            <div className="glass-panel rounded-2xl p-3 text-center">
              <div className="text-2xl font-bold text-secondary">{stats.totalServices}</div>
              <div className="text-xs text-muted-foreground mt-1">{t("nav.services")}</div>
            </div>
            <div className="glass-panel rounded-2xl p-3 text-center">
              <div className="text-2xl font-bold text-accent">{stats.unreadMessages}</div>
              <div className="text-xs text-muted-foreground mt-1">{t("nav.chat")}</div>
            </div>
            <div className="glass-panel rounded-2xl p-3 text-center">
              <div className="text-2xl font-bold text-destructive">{stats.unreadNotifications}</div>
              <div className="text-xs text-muted-foreground mt-1">{t("nav.notifications")}</div>
            </div>
          </div>
        )}

        {/* Apps Grid */}
        <div className="mb-4">
          <h3 className="text-sm font-medium text-muted-foreground mb-4">{t("home.myApps")}</h3>
          <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
            <SortableContext items={sortableIds} strategy={rectSortingStrategy}>
              <div className="grid grid-cols-4 sm:grid-cols-5 md:grid-cols-6 gap-4">
                {orderedApps?.map((app) => (
                  <SortableAppIcon
                    key={app.id}
                    app={app}
                    onClick={() => setLocation(app.route)}
                  />
                ))}
              </div>
            </SortableContext>
          </DndContext>
        </div>
      </div>

      {/* Bottom Dock */}
      <div className="fixed bottom-0 left-0 right-0 p-4 z-10">
        <div className="dock-glass rounded-3xl px-6 py-3 flex items-center justify-around max-w-sm mx-auto">
          {dockApps.slice(0, 4).map((app) => {
            const Icon = (LucideIcons as unknown as Record<string, React.ComponentType<{ size?: number; color?: string }>>)[app.iconName]
              ?? LucideIcons.Grid2X2;
            return (
              <button
                key={app.id}
                onClick={() => setLocation(app.route)}
                className="flex flex-col items-center gap-1 group"
              >
                <div
                  className="w-12 h-12 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform"
                  style={{ backgroundColor: `${app.color}25` }}
                >
                  <Icon size={22} color={app.color} />
                </div>
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}
