'use client';

import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { startTransition, useEffect, useOptimistic, useRef, useState } from 'react';
import { logout } from '@/app/(protected)/_actions';
import { markNotificationReadAction } from '@/app/(protected)/(basic)/_actions';
import {
  countUnread,
  resolveNotificationHref,
  type AdminNotification,
} from '@/lib/domain/notification';
import styles from './admin-header.module.scss';
import { HeaderIconButton } from './header-icon-button';

interface AdminHeaderProps {
  /** 프로필에 표시할 이름. 세션의 관리자 이름을 상위에서 받아온다. */
  adminName: string;
  /** 종 버튼이 펼치는 알림. 상위 레이아웃이 조회해 넘긴다. */
  notifications: AdminNotification[];
}

/**
 * Basic 레이아웃 헤더 — 시안 header(7028:7614)를 그대로 옮겼다. 좌측 로고, 우측에 아이콘
 * 버튼 3개와 프로필 pill이 온다.
 *
 * 시안과 다른 점 넷(전부 사용자 확정):
 *  - 로고: 시안(관리자페이지 QsFVFFUKGH68xAPVkF3SJ9 logo 5199:9639)의 정사각 심볼과
 *    "FOX PAY ADMIN" 2색 글자를 그대로 쓴다.
 *  - 사이드바 토글 버튼을 뺐다 — 시안에 없다.
 *  - 프로필 pill을 눌러 로그아웃한다. 시안에 로그아웃 자리가 없는데 다른 경로도 없어서,
 *    CaretDown이 이미 "열린다"고 알리고 있는 이 자리에 메뉴를 붙였다.
 *
 *  - 검색·사용자 아이콘 버튼을 뺐다 — 연결할 기능이 없어 눌러도 아무 일이 없었고, 사용자
 *    자리는 옆 프로필 pill과 겹쳤다.
 *
 * 이슈: 알림 읽음은 낙관적으로 표시한 뒤 `router.refresh()`로 서버 값에 되맞춘다 — 백엔드
 * PUT이 아직 행을 갱신하지 못해(notification-repository 참조) 새로 고치면 안 읽음으로 돌아온다.
 */
export function AdminHeader({ adminName, notifications }: AdminHeaderProps) {
  const router = useRouter();
  const [isNotificationOpen, setIsNotificationOpen] = useState(false);
  const notificationRef = useRef<HTMLDivElement>(null);
  const [optimisticNotifications, markReadOptimistically] = useOptimistic(
    notifications,
    (current, id: string) =>
      current.map((item) => (item.id === id ? { ...item, isRead: true } : item))
  );
  const unreadCount = countUnread(optimisticNotifications);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const profileRef = useRef<HTMLDivElement>(null);

  function openNotification(item: AdminNotification) {
    setIsNotificationOpen(false);
    if (item.isRead) {
      return;
    }
    startTransition(async () => {
      markReadOptimistically(item.id);
      await markNotificationReadAction(item.id);
      router.refresh();
    });
  }

  // 바깥을 누르거나 Esc를 누르면 닫는다 — 열린 동안에만 듣는다. 프로필·알림이 같은 규칙이라
  // 한 곳에서 처리하고, 하나를 열면 다른 하나는 닫는다.
  useEffect(() => {
    if (!isMenuOpen && !isNotificationOpen) {
      return;
    }

    function handlePointerDown(event: MouseEvent) {
      const target = event.target as Node;
      if (!profileRef.current?.contains(target)) {
        setIsMenuOpen(false);
      }
      if (!notificationRef.current?.contains(target)) {
        setIsNotificationOpen(false);
      }
    }

    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === 'Escape') {
        setIsMenuOpen(false);
        setIsNotificationOpen(false);
      }
    }

    document.addEventListener('mousedown', handlePointerDown);
    document.addEventListener('keydown', handleKeyDown);
    return () => {
      document.removeEventListener('mousedown', handlePointerDown);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isMenuOpen, isNotificationOpen]);

  return (
    <header className={styles.header}>
      <div className={styles.logo}>
        {/* 옆 글자가 같은 내용을 이미 말하므로 장식으로 둔다 — alt를 채우면 두 번 읽힌다. */}
        <Image
          src="/images/logo-foxpay-symbol.svg"
          alt=""
          width={28}
          height={28}
          className={styles.logoMark}
          priority
        />
        <span className={styles.title}>
          <span className={styles.titleStrong}>FOX PAY</span>{' '}
          <span className={styles.titleSub}>ADMIN</span>
        </span>
      </div>

      <div className={styles.fnc}>
        <div className={styles.btnGroup} ref={notificationRef}>
          <HeaderIconButton
            icon={<i className="fox-ico fox-ico-BellSimple" aria-hidden="true" />}
            label={unreadCount > 0 ? `알림 ${unreadCount}건` : '알림'}
            hasBadge={unreadCount > 0}
            isExpanded={isNotificationOpen}
            onAction={() => {
              setIsNotificationOpen((open) => !open);
              setIsMenuOpen(false);
            }}
          />

          {isNotificationOpen && (
            <div className={styles.notifications} role="menu">
              {optimisticNotifications.length === 0 ? (
                <p className={styles.notificationEmpty}>새 알림이 없습니다.</p>
              ) : (
                <ul className={styles.notificationList}>
                  {optimisticNotifications.map((item) => {
                    const href = resolveNotificationHref(item);
                    const className = `${styles.notification} ${
                      item.isRead ? '' : styles.notificationUnread
                    }`;
                    const body = (
                      <>
                        <span className={styles.notificationTitle}>
                          {item.title}
                        </span>
                        <span className={styles.notificationContent} title={item.content}>
                          {item.content}
                        </span>
                      </>
                    );
                    return (
                      <li key={item.id}>
                        {href ? (
                          <Link
                            href={href}
                            role="menuitem"
                            className={`${className} ${styles.notificationLink}`}
                            onClick={() => openNotification(item)}
                          >
                            {body}
                          </Link>
                        ) : (
                          <div className={className}>{body}</div>
                        )}
                      </li>
                    );
                  })}
                </ul>
              )}
            </div>
          )}
        </div>

        <div className={styles.profile} ref={profileRef}>
          <button
            type="button"
            className={styles.profileButton}
            aria-haspopup="menu"
            aria-expanded={isMenuOpen}
            onClick={() => setIsMenuOpen((open) => !open)}
          >
            {/* 시안은 프로필 사진 자리지만 관리자 사진을 받는 경로가 없어 사람 아이콘으로 채운다. */}
            <span className={styles.avatar}>
              <i className="fox-ico fox-ico--fill fox-ico-User" aria-hidden="true" />
            </span>
            <span className={styles.profileName}>{adminName}</span>
            <span className={styles.caret}>
              <i className="fox-ico fox-ico-CaretDown" aria-hidden="true" />
            </span>
          </button>

          {isMenuOpen && (
            <div className={styles.menu} role="menu">
              <form action={logout}>
                <button type="submit" role="menuitem" className={styles.menuItem}>
                  로그아웃
                </button>
              </form>
            </div>
          )}
        </div>
      </div>
    </header>
  );
}
