import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from "react";

export type NotificationCategory = "bookings" | "business" | "account" | "system";

export type AppNotification = {
  id: string;
  category: NotificationCategory;
  title: string;
  body: string;
  createdAt: string;
  read: boolean;
  business?: string;
  href?: string;
};

export type UserProfile = {
  firstName: string;
  lastName: string;
  email: string;
  emailVerified: boolean;
  mobile: string;
  mobileVerified: boolean;
  jobTitle: string;
  language: string;
  timeZone: string;
  avatarUrl: string | null;
};

export type Preferences = {
  theme: "light" | "dark" | "system";
  language: string;
  timeZone: string;
  dateFormat: "DD/MM/YYYY" | "MM/DD/YYYY" | "YYYY-MM-DD";
  timeFormat: "12h" | "24h";
  channels: { email: boolean; push: boolean; sms: boolean; inApp: boolean };
  types: Record<string, { email: boolean; push: boolean; inApp: boolean }>;
  twoFactor: boolean;
};

export type DeviceSession = {
  id: string;
  device: string;
  browser: string;
  location: string;
  lastActive: string;
  current: boolean;
};

export type ActivityEntry = {
  id: string;
  group: string;
  time: string;
  action: string;
  meta: string;
};

const PROFILE_KEY = "airfis.account.profile";
const PREFS_KEY = "airfis.account.prefs";
const NOTIF_KEY = "airfis.account.notifications";

export const NOTIFICATION_TYPES = [
  { key: "new_bookings", label: "New bookings", locked: false },
  { key: "booking_updates", label: "Booking updates", locked: false },
  { key: "customer_messages", label: "Customer messages", locked: false },
  { key: "business_updates", label: "Business updates", locked: false },
  { key: "account_security", label: "Account security", locked: true },
  { key: "promotional", label: "Promotional updates", locked: false },
] as const;

const defaultProfile: UserProfile = {
  firstName: "Edwin",
  lastName: "D",
  email: "edwin@example.com",
  emailVerified: true,
  mobile: "+91 98765 43210",
  mobileVerified: true,
  jobTitle: "Owner",
  language: "English",
  timeZone: "Asia/Kolkata (GMT +05:30)",
  avatarUrl: null,
};

const defaultPrefs: Preferences = {
  theme: "light",
  language: "English",
  timeZone: "Asia/Kolkata (GMT +05:30)",
  dateFormat: "DD/MM/YYYY",
  timeFormat: "12h",
  channels: { email: true, push: true, sms: false, inApp: true },
  types: {
    new_bookings: { email: true, push: true, inApp: true },
    booking_updates: { email: true, push: true, inApp: true },
    customer_messages: { email: true, push: true, inApp: true },
    business_updates: { email: true, push: false, inApp: true },
    account_security: { email: true, push: true, inApp: true },
    promotional: { email: false, push: false, inApp: false },
  },
  twoFactor: false,
};

const seedNotifications: AppNotification[] = [
  {
    id: "n1",
    category: "bookings",
    title: "New booking received",
    body: "A new booking has been received for Win Cars.",
    createdAt: new Date(Date.now() - 10 * 60_000).toISOString(),
    read: false,
    business: "win cars",
    href: "/partner/requests",
  },
  {
    id: "n2",
    category: "account",
    title: "Profile updated",
    body: "Your profile information was successfully updated.",
    createdAt: new Date(Date.now() - 60 * 60_000).toISOString(),
    read: false,
    href: "/profile",
  },
  {
    id: "n3",
    category: "system",
    title: "System maintenance",
    body: "Scheduled maintenance will happen tonight at 11:00 PM.",
    createdAt: new Date(Date.now() - 3 * 60 * 60_000).toISOString(),
    read: false,
  },
  {
    id: "n4",
    category: "business",
    title: "Business verification approved",
    body: "Win Automobiles has been verified and is now listed.",
    createdAt: new Date(Date.now() - 26 * 60 * 60_000).toISOString(),
    read: true,
    business: "win automobiles",
    href: "/partner/account",
  },
  {
    id: "n5",
    category: "bookings",
    title: "Booking completed",
    body: "Request AF-2043 was marked completed.",
    createdAt: new Date(Date.now() - 50 * 60 * 60_000).toISOString(),
    read: true,
    business: "win cars",
    href: "/partner/requests",
  },
];

export const DEVICE_SESSIONS: DeviceSession[] = [
  {
    id: "s1",
    device: "Windows PC",
    browser: "Chrome",
    location: "Chennai, India",
    lastActive: "Active now",
    current: true,
  },
  {
    id: "s2",
    device: "MacBook Pro",
    browser: "Chrome",
    location: "Chennai, India",
    lastActive: "Last active 2 hours ago",
    current: false,
  },
  {
    id: "s3",
    device: "iPhone 14",
    browser: "Safari",
    location: "Coimbatore, India",
    lastActive: "Last active yesterday",
    current: false,
  },
];

export const ACTIVITY_LOG: ActivityEntry[] = [
  { id: "a1", group: "Today", time: "11:32 AM", action: "Logged in", meta: "Chrome · Windows" },
  {
    id: "a2",
    group: "Today",
    time: "10:48 AM",
    action: "Updated profile",
    meta: "Chrome · Windows",
  },
  { id: "a3", group: "Yesterday", time: "4:20 PM", action: "Added new business", meta: "win cars" },
  {
    id: "a4",
    group: "Monday",
    time: "2:15 PM",
    action: "Changed password",
    meta: "Chrome · Windows",
  },
];

function load<T>(key: string, fallback: T): T {
  if (typeof window === "undefined") return fallback;
  try {
    const raw = window.localStorage.getItem(key);
    return raw ? ({ ...fallback, ...JSON.parse(raw) } as T) : fallback;
  } catch {
    return fallback;
  }
}

type Ctx = {
  profile: UserProfile;
  updateProfile: (patch: Partial<UserProfile>) => void;
  prefs: Preferences;
  updatePrefs: (patch: Partial<Preferences>) => void;
  notifications: AppNotification[];
  unreadCount: number;
  markRead: (id: string) => void;
  markAllRead: () => void;
  dismiss: (id: string) => void;
  clearAll: () => void;
};

const AccountContext = createContext<Ctx | null>(null);

export function AccountProvider({ children }: { children: ReactNode }) {
  const [profile, setProfile] = useState<UserProfile>(defaultProfile);
  const [prefs, setPrefs] = useState<Preferences>(defaultPrefs);
  const [notifications, setNotifications] = useState<AppNotification[]>(seedNotifications);

  useEffect(() => {
    setProfile(load(PROFILE_KEY, defaultProfile));
    setPrefs(load(PREFS_KEY, defaultPrefs));
    try {
      const raw = window.localStorage.getItem(NOTIF_KEY);
      if (raw) setNotifications(JSON.parse(raw));
    } catch {
      /* ignore */
    }
  }, []);

  function persist(key: string, value: unknown) {
    if (typeof window !== "undefined") window.localStorage.setItem(key, JSON.stringify(value));
  }

  const value = useMemo<Ctx>(() => {
    const setNotifs = (next: AppNotification[]) => {
      setNotifications(next);
      persist(NOTIF_KEY, next);
    };
    return {
      profile,
      updateProfile: (patch) =>
        setProfile((p) => {
          const next = { ...p, ...patch };
          persist(PROFILE_KEY, next);
          return next;
        }),
      prefs,
      updatePrefs: (patch) =>
        setPrefs((p) => {
          const next = { ...p, ...patch };
          persist(PREFS_KEY, next);
          return next;
        }),
      notifications,
      unreadCount: notifications.filter((n) => !n.read).length,
      markRead: (id) =>
        setNotifs(notifications.map((n) => (n.id === id ? { ...n, read: true } : n))),
      markAllRead: () => setNotifs(notifications.map((n) => ({ ...n, read: true }))),
      dismiss: (id) => setNotifs(notifications.filter((n) => n.id !== id)),
      clearAll: () => setNotifs([]),
    };
  }, [profile, prefs, notifications]);

  return <AccountContext.Provider value={value}>{children}</AccountContext.Provider>;
}

export function useAccount() {
  const ctx = useContext(AccountContext);
  if (!ctx) throw new Error("useAccount must be used inside AccountProvider");
  return ctx;
}

export function userInitials(p: UserProfile) {
  return `${p.firstName[0] ?? ""}${p.lastName[0] ?? ""}`.toUpperCase() || "U";
}

export function timeAgo(iso: string) {
  const diff = Date.now() - new Date(iso).getTime();
  const mins = Math.round(diff / 60_000);
  if (mins < 1) return "Just now";
  if (mins < 60) return `${mins} min ago`;
  const hours = Math.round(mins / 60);
  if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
  const days = Math.round(hours / 24);
  return `${days} day${days === 1 ? "" : "s"} ago`;
}
