/*
 * 시스템관리 — 공휴일 관리 (SCR-A · §5B). HolidayController 실배선.
 * 정본: GET /api/admin/holidays?year=(ADMIN) · POST/DELETE/PATCH /api/admin/holidays (ADMIN).
 * UI: 연도 선택 + 공휴일 목록(날짜·요일·명칭·대체 배지·휴무 토글·삭제) + 임시공휴일 추가 모달.
 * 데이터·시드(2024~2050)는 V41 소유 — 본 화면은 그 위 조회·임시공휴일 관리만. 캘린더 붉은색과 동일 소스.
 */
import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { ErrorState, Skeleton } from '../../components/ui/States';
import { Button } from '../../components/ui/Button';
import { KxDataTable, type KxColumn } from '../../components/KxDataTable';
import { IconPlus } from '../../components/ui/icons';
import { errMessage, useToast } from '../work/workShared';
import { holidayApi, type Holiday, type HolidayCreateBody } from './holidayApi';
import './admin-modules.css';

/** 데이터 미존재 시 폴백 연도 목록(V41 시드 범위). */
function fallbackYears(): number[] {
  const arr: number[] = [];
  for (let y = 2050; y >= 2024; y--) arr.push(y);
  return arr;
}
function weekdayIndex(ymd: string): number {
  const [y, m, d] = ymd.split('-').map(Number);
  return new Date(y, (m || 1) - 1, d || 1).getDay();
}

export function HolidayAdminPage() {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const { show, node: toast } = useToast();

  const yearsQ = useQuery({ queryKey: ['admin-holiday-years'], queryFn: holidayApi.years, retry: false });
  const years = yearsQ.data && yearsQ.data.length > 0 ? yearsQ.data : fallbackYears();
  const [year, setYear] = useState<number>(new Date().getFullYear());
  const [adding, setAdding] = useState(false);

  const listQ = useQuery({
    queryKey: ['admin-holidays', year],
    queryFn: () => holidayApi.adminList(year),
    retry: false,
  });
  const list = listQ.data ?? [];

  const createM = useMutation({
    mutationFn: (body: HolidayCreateBody) => holidayApi.create(body),
    onSuccess: () => {
      show(t('holiday.created'));
      setAdding(false);
      qc.invalidateQueries({ queryKey: ['admin-holidays'] });
      qc.invalidateQueries({ queryKey: ['admin-holiday-years'] });
    },
    onError: (e) => show(errMessage(e)),
  });
  const delM = useMutation({
    mutationFn: (ymd: string) => holidayApi.remove(ymd),
    onSuccess: () => {
      show(t('holiday.deleted'));
      qc.invalidateQueries({ queryKey: ['admin-holidays'] });
    },
    onError: (e) => show(errMessage(e)),
  });
  const toggleM = useMutation({
    mutationFn: ({ ymd, isHoliday }: { ymd: string; isHoliday: boolean }) =>
      holidayApi.toggle(ymd, isHoliday),
    onSuccess: () => {
      show(t('holiday.toggled'));
      qc.invalidateQueries({ queryKey: ['admin-holidays'] });
    },
    onError: (e) => show(errMessage(e)),
  });

  const count = useMemo(() => list.filter((h) => h.isHoliday).length, [list]);

  const columns = useMemo<KxColumn<Holiday>[]>(
    () => [
      { key: 'ymd', header: t('holiday.date'), value: (h) => h.ymd,
        render: (h) => <span className="kx-adm-mono" style={weekdayIndex(h.ymd) === 0 ? { color: 'var(--color-error)' } : undefined}>{h.ymd}</span> },
      { key: 'weekday', header: t('holiday.weekday'), sortable: false, value: (h) => t(`common.weekday.${weekdayIndex(h.ymd)}`),
        render: (h) => <span style={weekdayIndex(h.ymd) === 0 ? { color: 'var(--color-error)' } : undefined}>{t(`common.weekday.${weekdayIndex(h.ymd)}`)}</span> },
      { key: 'name', header: t('holiday.name'), value: (h) => h.name,
        render: (h) => <span className="kx-adm-tbl__strong" style={{ color: 'var(--color-error)' }}>{h.name}</span> },
      { key: 'type', header: t('holiday.type'), value: (h) => (h.isSubstitute ? t('holiday.substitute') : t('holiday.legal')),
        render: (h) => h.isSubstitute
          ? <span className="kx-adm-pill kx-adm-pill--neutral">{t('holiday.substitute')}</span>
          : <span className="kx-adm-muted">{t('holiday.legal')}</span> },
      { key: 'status', header: t('holiday.status'), value: (h) => (h.isHoliday ? t('holiday.on') : t('holiday.off')),
        render: (h) => <span className={`kx-adm-pill kx-adm-pill--${h.isHoliday ? 'success' : 'neutral'}`}>{h.isHoliday ? t('holiday.on') : t('holiday.off')}</span> },
      { key: 'manage', header: t('holiday.manage'), csv: false, sortable: false, searchable: false,
        thClassName: 'kx-adm-col-manage', tdClassName: 'kx-adm-col-manage',
        render: (h) => (
          <div className="kx-adm-tbl__actions">
            <Button variant="ghost" disabled={toggleM.isPending} onClick={() => toggleM.mutate({ ymd: h.ymd, isHoliday: !h.isHoliday })}>
              {h.isHoliday ? t('holiday.setOff') : t('holiday.setOn')}
            </Button>
            <Button variant="ghost" className="kx-adm-del" disabled={delM.isPending}
              onClick={() => { if (window.confirm(t('holiday.deleteConfirm', { name: h.name }))) delM.mutate(h.ymd); }}>
              {t('holiday.delete')}
            </Button>
          </div>
        ) },
    ],
    [t, toggleM, delM],
  );

  return (
    <div className="kx-page kx-adm">
      <header className="kx-adm__head">
        <div>
          <h1 className="kx-adm__title">{t('holiday.title')}</h1>
          <p className="kx-adm__subtitle">{t('holiday.subtitle')}</p>
        </div>
        <div className="kx-adm-tbl__actions">
          <label className="kx-adm-field" style={{ minWidth: 120 }}>
            <span className="kx-adm-field__label">{t('holiday.year')}</span>
            <select
              className="kx-adm-field__select"
              value={year}
              onChange={(e) => setYear(Number(e.target.value))}
            >
              {years.map((y) => (
                <option key={y} value={y}>
                  {t('holiday.yearLabel', { y })}
                </option>
              ))}
            </select>
          </label>
          <Button leadingIcon={<IconPlus size={16} />} onClick={() => setAdding(true)}>
            {t('holiday.add')}
          </Button>
        </div>
      </header>

      {listQ.isLoading && <Skeleton height={320} radius={12} />}
      {listQ.isError && !listQ.isLoading && (
        <ErrorState message={t('holiday.loadError')} onRetry={() => listQ.refetch()} />
      )}

      {!listQ.isLoading && !listQ.isError && (
        <section className="kx-card">
          <div className="kx-adm-codes__head">
            <h2>{t('holiday.listOf', { y: year })}</h2>
            <p className="kx-adm-muted">{t('holiday.count', { n: count })}</p>
          </div>
          <div className="kx-adm-codes__tbl">
            <KxDataTable
              columns={columns}
              rows={list}
              rowKey={(h) => h.ymd}
              csvFileName={`holidays_${year}`}
              ariaLabel={t('holiday.listOf', { y: year })}
              emptyTitle={t('holiday.emptyTitle')}
              emptyDescription={t('holiday.emptyDesc')}
            />
          </div>
        </section>
      )}

      {adding && (
        <HolidayAddModal
          defaultYear={year}
          existing={list.map((h) => h.ymd)}
          saving={createM.isPending}
          onClose={() => setAdding(false)}
          onSubmit={(body) => createM.mutate(body)}
        />
      )}
      {toast}
    </div>
  );
}

function HolidayAddModal({
  defaultYear,
  existing,
  saving,
  onClose,
  onSubmit,
}: {
  defaultYear: number;
  existing: string[];
  saving: boolean;
  onClose: () => void;
  onSubmit: (body: HolidayCreateBody) => void;
}) {
  const { t } = useTranslation();
  const [ymd, setYmd] = useState(`${defaultYear}-01-01`);
  const [name, setName] = useState('');
  const [isSubstitute, setIsSubstitute] = useState(false);
  const [error, setError] = useState<string | null>(null);

  function submit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd) || !name.trim()) {
      setError(t('holiday.errRequired'));
      return;
    }
    if (existing.includes(ymd)) {
      setError(t('holiday.errDup'));
      return;
    }
    onSubmit({ ymd, name: name.trim(), isSubstitute });
  }

  return (
    <div className="kx-adm-modal" role="dialog" aria-modal="true" aria-labelledby="holiday-modal-title">
      <div className="kx-adm-modal__backdrop" onClick={onClose} />
      <form className="kx-adm-modal__panel" onSubmit={submit}>
        <h2 id="holiday-modal-title" className="kx-adm-modal__title">{t('holiday.add')}</h2>
        <div className="kx-adm-modal__grid">
          <label className="kx-adm-field">
            <span className="kx-adm-field__label">{t('holiday.date')}</span>
            <input
              className="kx-adm-field__input"
              type="date"
              value={ymd}
              onChange={(e) => setYmd(e.target.value)}
            />
          </label>
          <label className="kx-adm-field">
            <span className="kx-adm-field__label">{t('holiday.name')}</span>
            <input className="kx-adm-field__input" value={name} onChange={(e) => setName(e.target.value)} />
          </label>
          <label className="kx-adm-field kx-adm-field--full" style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
            <input
              type="checkbox"
              checked={isSubstitute}
              onChange={(e) => setIsSubstitute(e.target.checked)}
            />
            <span className="kx-adm-field__label" style={{ margin: 0 }}>{t('holiday.substituteHint')}</span>
          </label>
        </div>
        {error && <p className="kx-adm-modal__error" role="alert">{error}</p>}
        <div className="kx-adm-modal__actions">
          <Button variant="ghost" type="button" onClick={onClose}>{t('holiday.cancel')}</Button>
          <Button type="submit" disabled={saving}>{saving ? t('holiday.saving') : t('holiday.save')}</Button>
        </div>
      </form>
    </div>
  );
}
