'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
  Bell,
  Briefcase,
  CheckCheck,
  ClipboardList,
  Handshake,
  MessageCircle,
  ShieldCheck,
  Star,
  type LucideIcon,
} from 'lucide-react';
import { DashboardLayout } from '@/components/layout/DashboardLayout';
import { Button } from '@/components/ui/button';
import { PortalLoading, PortalShell } from '@/components/portal/Portal';
import { api } from '@/lib/api';
import { cn, formatRelativeTime } from '@/lib/utils';
import { JOBS_FEATURE_ENABLED } from '@/lib/features';
import { useNotifications, AppNotification } from '@/contexts/NotificationContext';

interface NotificationsPageProps {
  role: 'customer' | 'worker';
}

type InboxFilter = 'all' | 'unread';

function notificationMeta(type: string): {
  icon: LucideIcon;
  label: string;
  tone: 'amber' | 'ink' | 'emerald' | 'rose' | 'slate';
} {
  if (type.startsWith('HIRE_')) {
    if (type === 'HIRE_REJECTED') {
      return { icon: Handshake, label: 'Hire', tone: 'rose' };
    }
    if (type === 'HIRE_COMPLETED') {
      return { icon: Handshake, label: 'Hire', tone: 'emerald' };
    }
    return { icon: Handshake, label: 'Hire', tone: 'amber' };
  }
  if (type === 'VERIFICATION_UPDATE') {
    return { icon: ShieldCheck, label: 'Verification', tone: 'ink' };
  }
  if (type === 'REVIEW_RECEIVED') {
    return { icon: Star, label: 'Review', tone: 'amber' };
  }
  if (type === 'MESSAGE_RECEIVED') {
    return { icon: MessageCircle, label: 'Message', tone: 'ink' };
  }
  if (type.startsWith('QUOTE_') || type === 'JOB_POSTED' || type === 'JOB_STATUS_CHANGED') {
    return { icon: Briefcase, label: 'Job', tone: 'ink' };
  }
  if (type === 'JOB_REACTION') {
    return { icon: ClipboardList, label: 'Update', tone: 'slate' };
  }
  return { icon: Bell, label: 'Update', tone: 'slate' };
}

const toneClasses = {
  amber: 'bg-[var(--home-amber)] text-white',
  ink: 'bg-[var(--home-ink)] text-white',
  emerald: 'bg-emerald-600 text-white',
  rose: 'bg-rose-600 text-white',
  slate: 'bg-slate-500 text-white',
} as const;

export function NotificationsPage({ role }: NotificationsPageProps) {
  const router = useRouter();
  const { refreshUnreadCount, markAsRead, markAllAsRead } = useNotifications();
  const [notifications, setNotifications] = useState<AppNotification[]>([]);
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState<InboxFilter>('all');
  const [markingAll, setMarkingAll] = useState(false);

  const messagesBase = `/${role}/messages`;

  const load = useCallback(async () => {
    try {
      const res = await api<{ data: AppNotification[] }>('/notifications?limit=50');
      setNotifications(res.data || []);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, []);

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

  useEffect(() => {
    const onFocus = () => {
      void load();
      void refreshUnreadCount();
    };
    window.addEventListener('focus', onFocus);
    return () => window.removeEventListener('focus', onFocus);
  }, [load, refreshUnreadCount]);

  const handleClick = async (notification: AppNotification) => {
    if (!notification.isRead) {
      await markAsRead(notification.id);
      setNotifications((prev) =>
        prev.map((n) => (n.id === notification.id ? { ...n, isRead: true } : n))
      );
    }

    const conversationId = notification.data?.conversationId;
    if (conversationId) {
      router.push(`${messagesBase}/${conversationId}`);
      return;
    }

    const hireInvitationId = notification.data?.hireInvitationId;
    if (hireInvitationId || notification.type?.startsWith('HIRE_')) {
      router.push(`/${role}/hire-invitations`);
      return;
    }

    const href = typeof notification.data?.href === 'string' ? notification.data.href : null;
    if (href) {
      router.push(href);
      return;
    }

    if (notification.type === 'VERIFICATION_UPDATE') {
      router.push(`/${role}/verification`);
      return;
    }

    if (notification.type === 'REVIEW_RECEIVED') {
      router.push(role === 'worker' ? '/worker/ratings' : '/customer/reviews');
      return;
    }

    const jobId = notification.data?.jobId;
    if (jobId && JOBS_FEATURE_ENABLED) {
      router.push(`/${role}/jobs/${jobId}`);
    }
  };

  const handleMarkAllRead = async () => {
    setMarkingAll(true);
    try {
      await markAllAsRead();
      setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true })));
      await refreshUnreadCount();
    } finally {
      setMarkingAll(false);
    }
  };

  const unread = useMemo(
    () => notifications.filter((n) => !n.isRead).length,
    [notifications]
  );

  const visible = useMemo(() => {
    if (filter === 'unread') return notifications.filter((n) => !n.isRead);
    return notifications;
  }, [notifications, filter]);

  const emptyCopy = JOBS_FEATURE_ENABLED
    ? 'Updates about quotes, messages, and jobs will appear here.'
    : role === 'worker'
      ? 'Hire invites, reviews, and account updates will show up here.'
      : 'Hire updates, verification, and account alerts will show up here.';

  return (
    <DashboardLayout role={role} title="Notifications">
      <PortalShell>
        {/* Header */}
        <section className="border border-[#e2ddd2] bg-[#fffdf9]">
          <div className="flex flex-col gap-4 px-4 py-4 sm:flex-row sm:items-start sm:justify-between sm:px-5 sm:py-5">
            <div className="min-w-0">
              <p className="text-[10px] font-semibold uppercase tracking-[0.14em] text-[var(--home-amber)]">
                Inbox
              </p>
              <h2 className="home-display mt-0.5 text-2xl font-bold text-[var(--home-ink)]">
                Notifications
              </h2>
              <p className="mt-1 text-sm text-muted">
                {unread > 0
                  ? `You have ${unread} unread notification${unread === 1 ? '' : 's'}.`
                  : 'You’re all caught up.'}
              </p>
            </div>

            {unread > 0 ? (
              <Button
                variant="outline"
                size="sm"
                className="shrink-0 rounded-none"
                disabled={markingAll}
                onClick={handleMarkAllRead}
              >
                <CheckCheck className="mr-1.5 h-4 w-4" />
                {markingAll ? 'Marking…' : 'Mark all as read'}
              </Button>
            ) : null}
          </div>

          <div className="flex border-t border-[#e2ddd2]">
            {(
              [
                { key: 'all' as const, label: 'All', count: notifications.length },
                { key: 'unread' as const, label: 'Unread', count: unread },
              ] as const
            ).map((tab) => {
              const active = filter === tab.key;
              return (
                <button
                  key={tab.key}
                  type="button"
                  onClick={() => setFilter(tab.key)}
                  className={cn(
                    'relative flex flex-1 items-center justify-center gap-2 px-3 py-2.5 text-sm font-semibold transition-colors',
                    active
                      ? 'bg-white text-[var(--home-ink)]'
                      : 'text-muted hover:bg-white/70 hover:text-slate-800'
                  )}
                >
                  {tab.label}
                  <span
                    className={cn(
                      'min-w-[1.25rem] px-1.5 py-0.5 text-center text-[10px] font-bold tabular-nums',
                      active
                        ? 'bg-[var(--home-ink)] text-white'
                        : 'bg-[#efeae0] text-slate-600'
                    )}
                  >
                    {tab.count}
                  </span>
                  {active ? (
                    <span className="absolute inset-x-0 bottom-0 h-0.5 bg-[var(--home-amber)]" />
                  ) : null}
                </button>
              );
            })}
          </div>
        </section>

        {loading ? (
          <PortalLoading label="Loading notifications…" />
        ) : notifications.length === 0 ? (
          <section className="flex flex-col items-center border border-[#e2ddd2] bg-white px-6 py-14 text-center">
            <div className="mb-4 flex h-14 w-14 items-center justify-center bg-[var(--home-sand)] text-[var(--home-ink)]">
              <Bell className="h-7 w-7" />
            </div>
            <h3 className="font-bold text-[var(--home-ink)]">No notifications yet</h3>
            <p className="mt-2 max-w-sm text-sm leading-relaxed text-muted">{emptyCopy}</p>
          </section>
        ) : visible.length === 0 ? (
          <section className="flex flex-col items-center border border-[#e2ddd2] bg-white px-6 py-14 text-center">
            <div className="mb-4 flex h-14 w-14 items-center justify-center bg-[var(--home-sand)] text-[var(--home-ink)]">
              <CheckCheck className="h-7 w-7" />
            </div>
            <h3 className="font-bold text-[var(--home-ink)]">No unread notifications</h3>
            <p className="mt-2 max-w-sm text-sm leading-relaxed text-muted">
              Switch to All to see your earlier updates.
            </p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="mt-4 rounded-none"
              onClick={() => setFilter('all')}
            >
              Show all
            </Button>
          </section>
        ) : (
          <section className="overflow-hidden border border-[#e2ddd2] bg-[var(--home-sand)]/20">
            <ul className="divide-y divide-[#ebe6db]">
              {visible.map((n) => {
                const meta = notificationMeta(n.type);
                const Icon = meta.icon;
                return (
                  <li key={n.id}>
                    <button
                      type="button"
                      onClick={() => handleClick(n)}
                      className={cn(
                        'flex w-full items-start gap-3 px-4 py-4 text-left transition-colors sm:px-5',
                        n.isRead
                          ? 'bg-[#fffdf9] hover:bg-white'
                          : 'bg-white shadow-[inset_3px_0_0_var(--home-amber)] hover:bg-[#fffdf9]'
                      )}
                    >
                      <span
                        className={cn(
                          'mt-0.5 flex h-10 w-10 shrink-0 items-center justify-center',
                          toneClasses[meta.tone]
                        )}
                      >
                        <Icon className="h-5 w-5" />
                      </span>

                      <div className="min-w-0 flex-1">
                        <div className="flex items-start justify-between gap-3">
                          <div className="min-w-0">
                            <div className="flex flex-wrap items-center gap-2">
                              <p
                                className={cn(
                                  'text-sm text-[var(--home-ink)]',
                                  n.isRead ? 'font-semibold' : 'font-bold'
                                )}
                              >
                                {n.title}
                              </p>
                              {!n.isRead ? (
                                <span className="bg-[var(--home-amber)] px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wide text-white">
                                  New
                                </span>
                              ) : null}
                            </div>
                            <p className="mt-1 text-[11px] font-semibold uppercase tracking-wide text-muted">
                              {meta.label}
                            </p>
                          </div>
                          <time className="shrink-0 text-[11px] tabular-nums text-slate-400">
                            {formatRelativeTime(n.createdAt)}
                          </time>
                        </div>
                        <p className="mt-1.5 text-sm leading-relaxed text-slate-600">{n.message}</p>
                      </div>
                    </button>
                  </li>
                );
              })}
            </ul>
          </section>
        )}
      </PortalShell>
    </DashboardLayout>
  );
}
