/*
 * W12 시스템관리 — 역할-메뉴 접근 매핑(역할 × 메뉴 read/write 매트릭스).
 * 정본: GET/POST /api/admin/roles/{roleCode}/menus (RoleMenuController). 역할 목록은 기존 roleApi(RoleController).
 * 기존 역할/권한(rolePerm=RoleAdminPage)과 직교 — 여긴 메뉴 접근 매핑.
 */
import { useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { Button } from '../../components/ui/Button';
import { errMessage, useToast } from '../work/workShared';
import { roleApi } from './adminCrudApi';
import { roleMenuApi, type RoleMenu } from './systemBasicsApi';
import './admin-modules.css';

export function RoleMenuAdminPage() {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const { show, node: toast } = useToast();
  const rolesQ = useQuery({ queryKey: ['admin-roles'], queryFn: roleApi.list, retry: false });
  const [selected, setSelected] = useState<string | null>(null);
  const roles = rolesQ.data ?? [];

  useEffect(() => {
    if (!selected && roles.length > 0) setSelected(roles[0].roleCode);
  }, [roles, selected]);

  const menusQ = useQuery({
    queryKey: ['admin-role-menus', selected],
    queryFn: () => roleMenuApi.list(selected!),
    enabled: !!selected,
    retry: false,
  });

  const [draft, setDraft] = useState<Record<string, { readYn: string; writeYn: string; mapped: boolean }>>({});
  useEffect(() => {
    if (menusQ.data) {
      const d: Record<string, { readYn: string; writeYn: string; mapped: boolean }> = {};
      for (const m of menusQ.data) d[m.menuId] = { readYn: m.readYn, writeYn: m.writeYn, mapped: m.mapped };
      setDraft(d);
    }
  }, [menusQ.data]);

  const saveM = useMutation({
    mutationFn: () => {
      const menus = Object.entries(draft)
        .filter(([, v]) => v.mapped)
        .map(([menuId, v]) => ({ menuId, readYn: v.readYn, writeYn: v.writeYn }));
      return roleMenuApi.save(selected!, { menus });
    },
    onSuccess: () => { show(t('roleMenu.saved')); qc.invalidateQueries({ queryKey: ['admin-role-menus', selected] }); },
    onError: (e) => show(errMessage(e)),
  });

  function toggleMapped(m: RoleMenu, on: boolean) {
    setDraft((d) => ({ ...d, [m.menuId]: { ...d[m.menuId], mapped: on, readYn: on ? (d[m.menuId]?.readYn || 'Y') : 'N' } }));
  }
  function setFlag(m: RoleMenu, key: 'readYn' | 'writeYn', on: boolean) {
    setDraft((d) => ({ ...d, [m.menuId]: { ...d[m.menuId], [key]: on ? 'Y' : 'N' } }));
  }

  const menus = menusQ.data ?? [];

  return (
    <div className="kx-page kx-adm">
      <header className="kx-adm__head">
        <div>
          <h1 className="kx-adm__title">{t('roleMenu.title')}</h1>
          <p className="kx-adm__subtitle">{t('roleMenu.subtitle')}</p>
        </div>
        <Button disabled={!selected || saveM.isPending} onClick={() => saveM.mutate()}>
          {saveM.isPending ? t('sysadmin.saving') : t('sysadmin.save')}
        </Button>
      </header>

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

      {!rolesQ.isLoading && !rolesQ.isError && (
        roles.length === 0 ? (
          <EmptyState title={t('roleMenu.noRoles')} />
        ) : (
          <div className="kx-adm-matrix">
            <section className="kx-card kx-adm-matrix__roles" aria-label={t('roleMenu.roleList')}>
              <div className="kx-adm-codes__head"><h2>{t('roleMenu.role')}</h2></div>
              <ul className="kx-adm-glist">
                {roles.map((r) => (
                  <li key={r.roleCode}>
                    <button type="button" className={`kx-adm-gitem ${r.roleCode === selected ? 'is-active' : ''}`}
                            onClick={() => setSelected(r.roleCode)}>
                      <span className="kx-adm-gitem__name">{r.roleName}</span>
                      <span className="kx-adm-gitem__code">{r.roleCode}</span>
                    </button>
                  </li>
                ))}
              </ul>
            </section>

            <section className="kx-card kx-adm-matrix__perms" aria-label={t('roleMenu.matrix')}>
              {menusQ.isLoading && <Skeleton height={280} radius={8} />}
              {menusQ.isError && !menusQ.isLoading && <ErrorState message={t('roleMenu.loadError')} onRetry={() => menusQ.refetch()} />}
              {!menusQ.isLoading && !menusQ.isError && (
                menus.length === 0 ? (
                  <EmptyState title={t('roleMenu.noMenus')} />
                ) : (
                  <div className="kx-table-scroll">
                    <table className="kx-table kx-table--zebra">
                      <thead>
                        <tr>
                          <th>{t('roleMenu.colMenu')}</th>
                          <th className="kx-adm-center">{t('roleMenu.colAccess')}</th>
                          <th className="kx-adm-center">{t('roleMenu.colRead')}</th>
                          <th className="kx-adm-center">{t('roleMenu.colWrite')}</th>
                        </tr>
                      </thead>
                      <tbody>
                        {menus.map((m) => {
                          const st = draft[m.menuId] ?? { readYn: 'N', writeYn: 'N', mapped: false };
                          return (
                            <tr key={m.menuId}>
                              <td style={{ paddingLeft: m.parentId ? 28 : 12 }}>{m.menuName}</td>
                              <td className="kx-adm-center">
                                <input type="checkbox" checked={st.mapped} onChange={(e) => toggleMapped(m, e.target.checked)} />
                              </td>
                              <td className="kx-adm-center">
                                <input type="checkbox" checked={st.readYn === 'Y'} disabled={!st.mapped}
                                       onChange={(e) => setFlag(m, 'readYn', e.target.checked)} />
                              </td>
                              <td className="kx-adm-center">
                                <input type="checkbox" checked={st.writeYn === 'Y'} disabled={!st.mapped}
                                       onChange={(e) => setFlag(m, 'writeYn', e.target.checked)} />
                              </td>
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                  </div>
                )
              )}
            </section>
          </div>
        )
      )}
      {toast}
    </div>
  );
}
