'use client';

import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { FoxBadge, type FoxBadgeColor } from '@fox/core/components/fox-badge';
import { FoxButton } from '@fox/core/components/fox-button';
import { FoxButtonGroup } from '@fox/core/components/fox-button-group';
import {
  FoxListContainer,
  type FoxListColumn,
} from '@fox/core/components/fox-list-container';
import { FoxSelectText } from '@fox/core/components/fox-select-text';
import {
  FoxArrowsDownUpIcon,
  FoxDownloadSimpleIcon,
  FoxPlusIcon,
} from '@fox/core/icons';
import {
  formatAdminRoleLabel,
  formatOptionalValue,
  type AdminMember,
} from '@/lib/domain/admin-member';
import {
  ADMIN_MEMBERS_EXCEL_PATH,
  ADMIN_MEMBER_PAGE_SIZE_OPTIONS,
  ADMIN_MEMBER_SEARCH_FIELD_OPTIONS,
  ADMIN_MEMBER_SORT_OPTIONS,
  buildAdminMemberHref,
  type AdminMemberPageSize,
  type AdminMemberQuery,
  type AdminMemberSearchField,
  type AdminMemberSortOption,
} from '@/lib/domain/admin-member-query';
import { AdminMemberCreateModal } from './admin-member-create-modal';
import { AdminMemberRowActions } from './admin-member-row-actions';

interface AdminMemberListProps {
  items: AdminMember[];
  query: AdminMemberQuery;
  /** 화면이 실제로 보여주는 페이지 — 순번 계산의 기준이다. */
  currentPage: number;
  totalPages: number;
  totalCount: number;
  /** 현재 로그인한 관리자의 id — 본인 행의 삭제 버튼을 막는 데 쓴다. */
  currentAdminId: string;
}

/** 폭이 고정되지 않은 세 열이 나눠 갖는 몫 — 시안 1552px 기준 (1552 - 고정열 720) / 3. */
const FILL_COLUMN_WIDTH = 277;

/**
 * 역할 배지의 색. 시안이 최고관리자는 accent(붉은 계열), 그 외는 primary(파란 계열)로
 * 구분한다 — 색은 시각 결정이라 도메인(`admin-member.ts`)이 아니라 여기가 갖는다.
 * 모르는 코드는 이름을 지어내지 않듯 색도 입히지 않는다(neutral).
 */
const BADGE_COLOR_BY_ROLE: Record<string, FoxBadgeColor> = {
  ROLE_SYSTEM: 'accent',
  ROLE_ADMIN: 'primary',
};

/**
 * 관리자 회원 목록 — 시안: 관리자페이지(QsFVFFUKGH68xAPVkF3SJ9) ADM_ADM_101 (5227:1545)
 *
 * 뼈대는 `FoxListContainer`가 전부 그린다(학생 회원 목록과 같은 구성). 이 파일이 갖는 것은
 * 이 화면 고유의 것뿐이다 — 8개 열의 정의, 정렬·페이지 크기 셀렉트, 툴바 버튼 두 개,
 * 그리고 URL을 갱신하는 방법.
 *
 * 이동은 두 갈래로 나뉜다. 페이지네이션은 `buildHref`로 **링크**가 되고(주소가 곧 상태라
 * 새로고침·뒤로가기·공유가 그대로 동작한다), 검색·정렬·페이지 크기는 컨트롤이 눌린 순간
 * `router.replace`로 같은 주소 규칙을 태운다. 어느 쪽이든 목록을 다시 그리는 것은 서버다.
 *
 * [엑셀 다운로드]는 네이티브 GET 폼이다 — 응답이 첨부파일(Content-Disposition)이라 라우터
 * 내비게이션으로는 처리할 수 없고, 브라우저가 화면을 둔 채 파일만 내려받는다. 검색·페이징 값을
 * 싣지 않는 것이 사양이다(파일은 항상 전체 데이터).
 */
export function AdminMemberList({
  items,
  query,
  currentPage,
  totalPages,
  totalCount,
  currentAdminId,
}: AdminMemberListProps) {
  const router = useRouter();
  const [isCreateOpen, setIsCreateOpen] = useState(false);

  /** 목록 조건이 바뀌면 늘 1페이지로 되돌린다 — 이전 페이지 번호는 새 조건에서 의미가 다르다. */
  function go(patch: Partial<AdminMemberQuery>) {
    router.replace(buildAdminMemberHref(query, { ...patch, page: 1 }));
  }

  const offset = (currentPage - 1) * query.pageSize;

  const columns: FoxListColumn<AdminMember>[] = [
    {
      key: 'no',
      header: '번호',
      width: 80,
      // 저장된 값이 아니라 전체 건수에서 거꾸로 세는 표시 순번이다 — 기본 정렬이 생성일
      // 최신순이라 "가장 최근에 만든 계정이 가장 큰 번호"가 된다.
      render: (_row, index) => totalCount - offset - index,
    },
    // 이름·아이디·이메일은 시안에서 남는 폭을 똑같이 나눠 갖는다(1552 기준 각 277). 폭을
    // 비워 두면 표가 글자 길이대로 나눠 이메일 열만 넓어져 시안과 어긋난다.
    { key: 'name', header: '이름', width: FILL_COLUMN_WIDTH },
    { key: 'loginId', header: '아이디', width: FILL_COLUMN_WIDTH },
    {
      key: 'phoneNumber',
      header: '휴대전화번호',
      width: 200,
      render: (row) => formatOptionalValue(row.phoneNumber),
    },
    {
      key: 'email',
      header: '이메일',
      width: FILL_COLUMN_WIDTH,
      render: (row) => formatOptionalValue(row.email),
    },
    {
      key: 'role',
      header: '역할',
      width: 120,
      render: (row) => (
        <FoxBadge
          type="pastel"
          color={BADGE_COLOR_BY_ROLE[row.roleCode] ?? 'neutral'}
          size="md"
        >
          {formatAdminRoleLabel(row.roleCode)}
        </FoxBadge>
      ),
    },
    {
      key: 'createdAt',
      header: '생성일',
      width: 160,
      render: (row) => formatOptionalValue(row.createdAt),
    },
    {
      key: 'actions',
      header: '관리',
      width: 160,
      render: (row) => (
        <AdminMemberRowActions
          member={row}
          isSelf={row.id === currentAdminId}
        />
      ),
    },
  ];

  return (
    <>
      <FoxListContainer<AdminMember>
        title="관리자 회원 목록"
        breadcrumb={[
          { label: '홈', href: '/' },
          { label: '관리자정보관리' },
          { label: '관리자 회원' },
        ]}
        caption="관리자 회원 목록"
        columns={columns}
        rows={items}
        rowKey={(row) => row.id}
        totalCount={totalCount}
        emptyMessage="검색 결과가 없습니다. 다른 검색어로 다시 시도해 주세요."
        sorts={
          <>
            <FoxSelectText
              size="sm"
              ariaLabel="정렬"
              icon={<FoxArrowsDownUpIcon />}
              options={ADMIN_MEMBER_SORT_OPTIONS.map((option) => ({
                value: option.value,
                label: option.label,
              }))}
              value={query.sort}
              onValueChange={(value) => go({ sort: value as AdminMemberSortOption })}
            />
            <FoxSelectText
              size="sm"
              ariaLabel="페이지 크기"
              options={ADMIN_MEMBER_PAGE_SIZE_OPTIONS.map((size) => ({
                value: String(size),
                label: `${size}개씩 보기`,
              }))}
              value={String(query.pageSize)}
              onValueChange={(value) =>
                go({ pageSize: Number(value) as AdminMemberPageSize })
              }
            />
          </>
        }
        searchFields={ADMIN_MEMBER_SEARCH_FIELD_OPTIONS.map((option) => ({
          value: option.value,
          label: option.label,
        }))}
        searchField={query.searchField}
        keyword={query.keyword}
        toolbarActions={
          <FoxButtonGroup size="md">
            <form action={ADMIN_MEMBERS_EXCEL_PATH} method="get">
              <FoxButton
                type="secondary"
                size="md"
                htmlType="submit"
                leadingIcon={<FoxDownloadSimpleIcon />}
                label="엑셀 다운로드"
              />
            </form>
            <FoxButton
              type="primary"
              size="md"
              leadingIcon={<FoxPlusIcon />}
              label="신규 등록"
              onAction={() => setIsCreateOpen(true)}
            />
          </FoxButtonGroup>
        }
        page={currentPage}
        totalPages={totalPages}
        buildHref={(patch) =>
          buildAdminMemberHref(query, { page: Number(patch.page ?? 1) })
        }
        onQueryChange={(patch) => {
          if (patch.keyword !== undefined || patch.searchField !== undefined) {
            go({
              keyword: String(patch.keyword ?? ''),
              searchField: (patch.searchField ??
                query.searchField) as AdminMemberSearchField,
            });
          }
        }}
      />
      {isCreateOpen && (
        <AdminMemberCreateModal onClose={() => setIsCreateOpen(false)} />
      )}
    </>
  );
}
