import type { PermTreeNode, RoleWithPermissions } from '@common/services/authApi';
import type { PermState, OperCode } from '../PermissionsPanel';
import { OPER_CODES, OPER_FULL_LABELS, OPER_LABELS, buildEffectiveStates } from '../PermissionsPanel';
import { TreeRow } from './TreeRow';
import { PermLegend } from './PermLegend';

interface RolePermTabProps {
  roles: RoleWithPermissions[];
  permTree: PermTreeNode[];
  rolePerms: Map<number, Map<string, boolean>>;
  setRolePerms: React.Dispatch<React.SetStateAction<Map<number, Map<string, boolean>>>>;
  selectedRoleSn: number | null;
  setSelectedRoleSn: (sn: number | null) => void;
  dirty: boolean;
  saving: boolean;
  saveError: string | null;
  handleSave: () => Promise<void>;
  handleToggleExpand: (code: string) => void;
  handleTogglePerm: (code: string, oper: OperCode, currentState: PermState) => void;
  expanded: Set<string>;
  flatNodes: PermTreeNode[];
  editingRoleSn: number | null;
  editRoleName: string;
  setEditRoleName: (name: string) => void;
  handleStartEditName: (role: RoleWithPermissions) => void;
  handleSaveRoleName: (roleSn: number) => Promise<void>;
  setEditingRoleSn: (sn: number | null) => void;
  toggleDefault: (roleSn: number) => Promise<void>;
  handleDeleteRole: (roleSn: number, roleName: string) => Promise<void>;
  showCreateForm: boolean;
  setShowCreateForm: (show: boolean) => void;
  setCreateError: (err: string) => void;
  newRoleCode: string;
  setNewRoleCode: (code: string) => void;
  newRoleName: string;
  setNewRoleName: (name: string) => void;
  newRoleDesc: string;
  setNewRoleDesc: (desc: string) => void;
  creating: boolean;
  createError: string;
  handleCreateRole: () => Promise<void>;
}

export function RolePermTab({
  roles,
  permTree,
  selectedRoleSn,
  setSelectedRoleSn,
  dirty,
  saving,
  saveError,
  handleSave,
  handleToggleExpand,
  handleTogglePerm,
  expanded,
  flatNodes,
  rolePerms,
  editingRoleSn,
  editRoleName,
  setEditRoleName,
  handleStartEditName,
  handleSaveRoleName,
  setEditingRoleSn,
  toggleDefault,
  handleDeleteRole,
  showCreateForm,
  setShowCreateForm,
  setCreateError,
  newRoleCode,
  setNewRoleCode,
  newRoleName,
  setNewRoleName,
  newRoleDesc,
  setNewRoleDesc,
  creating,
  createError,
  handleCreateRole,
}: RolePermTabProps) {
  const currentStateMap = selectedRoleSn
    ? buildEffectiveStates(flatNodes, rolePerms.get(selectedRoleSn) ?? new Map())
    : new Map<string, PermState>();

  return (
    <>
      {/* 헤더 액션 버튼 */}
      <div
        className="flex items-center gap-2 px-4 py-2 border-b border-stroke"
        style={{ flexShrink: 0 }}
      >
        <button
          onClick={() => {
            setShowCreateForm(true);
            setCreateError('');
          }}
          className="px-3 py-1.5 text-label-2 font-semibold rounded-md border border-color-accent text-color-accent hover:bg-[rgba(6,182,212,0.08)] transition-all font-korean"
        >
          + 역할 추가
        </button>
        <button
          onClick={handleSave}
          disabled={!dirty || saving}
          className={`px-3 py-1.5 text-label-2 font-semibold rounded-md transition-all font-korean ${
            dirty
              ? 'bg-color-accent text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)]'
              : 'bg-bg-card text-fg-disabled cursor-not-allowed'
          }`}
        >
          {saving ? '저장 중...' : '변경사항 저장'}
        </button>
        {saveError && (
          <span className="text-label-2 text-color-danger font-korean">{saveError}</span>
        )}
      </div>

      {/* 역할 탭 바 */}
      <div
        className="flex items-center gap-1.5 px-4 py-2 border-b border-stroke bg-bg-surface overflow-x-auto"
        style={{ flexShrink: 0 }}
      >
        {roles.map((role) => {
          const isSelected = selectedRoleSn === role.sn;
          return (
            <div key={role.sn} className="flex items-center gap-0.5 flex-shrink-0">
              <button
                onClick={() => setSelectedRoleSn(role.sn)}
                className={`px-2.5 py-1 text-label-2 font-semibold rounded-md transition-all font-korean ${
                  isSelected
                    ? 'border-2 border-color-accent text-color-accent shadow-[0_0_8px_rgba(6,182,212,0.2)]'
                    : 'border border-stroke text-fg-disabled hover:border-stroke-light hover:text-fg-sub'
                }`}
              >
                {editingRoleSn === role.sn ? (
                  <input
                    type="text"
                    value={editRoleName}
                    onChange={(e) => setEditRoleName(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter') handleSaveRoleName(role.sn);
                      if (e.key === 'Escape') setEditingRoleSn(null);
                    }}
                    onBlur={() => handleSaveRoleName(role.sn)}
                    onClick={(e) => e.stopPropagation()}
                    autoFocus
                    className="w-20 px-1 py-0 text-label-2 font-semibold bg-bg-elevated border border-color-accent rounded text-center text-fg focus:outline-none font-korean"
                  />
                ) : (
                  <span onDoubleClick={() => handleStartEditName(role)}>{role.name}</span>
                )}
                <span className="ml-1 text-caption font-mono opacity-50">{role.code}</span>
                {role.isDefault && (
                  <span className="ml-1 text-caption text-color-accent">기본</span>
                )}
              </button>
              {isSelected && (
                <div className="flex items-center gap-0.5">
                  <button
                    onClick={() => toggleDefault(role.sn)}
                    className={`px-1.5 py-0.5 text-caption rounded transition-all font-korean ${
                      role.isDefault
                        ? 'bg-[rgba(6,182,212,0.15)] text-color-accent'
                        : 'text-fg-disabled hover:text-fg-sub'
                    }`}
                    title="신규 사용자 기본 역할 설정"
                  >
                    {role.isDefault ? '기본역할' : '기본설정'}
                  </button>
                  {role.code !== 'ADMIN' && (
                    <button
                      onClick={() => handleDeleteRole(role.sn, role.name)}
                      className="w-5 h-5 flex items-center justify-center text-fg-disabled hover:text-color-danger transition-colors"
                      title="역할 삭제"
                    >
                      <svg
                        width="10"
                        height="10"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        strokeWidth="2.5"
                      >
                        <line x1="18" y1="6" x2="6" y2="18" />
                        <line x1="6" y1="6" x2="18" y2="18" />
                      </svg>
                    </button>
                  )}
                </div>
              )}
            </div>
          );
        })}
      </div>

      {/* 범례 */}
      <PermLegend />

      {/* CRUD 매트릭스 테이블 */}
      {selectedRoleSn ? (
        <div className="flex-1 overflow-auto">
          <table className="w-full">
            <thead>
              <tr className="border-b border-stroke bg-bg-surface sticky top-0 z-10">
                <th className="px-3 py-1.5 text-left text-caption font-semibold text-fg-disabled font-korean min-w-[200px]">
                  기능
                </th>
                {OPER_CODES.map((oper) => (
                  <th key={oper} className="px-1 py-1.5 text-center w-12">
                    <div className="text-caption font-semibold text-fg-sub">
                      {OPER_LABELS[oper]}
                    </div>
                    <div className="text-caption text-fg-disabled font-korean">
                      {OPER_FULL_LABELS[oper]}
                    </div>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {permTree.map((rootNode) => (
                <TreeRow
                  key={rootNode.code}
                  node={rootNode}
                  stateMap={currentStateMap}
                  expanded={expanded}
                  onToggleExpand={handleToggleExpand}
                  onTogglePerm={handleTogglePerm}
                />
              ))}
            </tbody>
          </table>
        </div>
      ) : (
        <div className="flex-1 flex items-center justify-center text-fg-disabled text-body-2 font-korean">
          역할을 선택하세요
        </div>
      )}

      {/* 역할 생성 모달 */}
      {showCreateForm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="w-[400px] bg-bg-surface rounded-lg border border-stroke shadow-2xl">
            <div className="px-5 py-4 border-b border-stroke">
              <h3 className="text-body-2 font-bold text-fg font-korean">새 역할 추가</h3>
            </div>
            <div className="px-5 py-4 flex flex-col gap-3">
              <div>
                <label className="text-label-2 text-fg-disabled font-korean block mb-1">
                  역할 코드
                </label>
                <input
                  type="text"
                  value={newRoleCode}
                  onChange={(e) =>
                    setNewRoleCode(e.target.value.toUpperCase().replace(/[^A-Z0-9_]/g, ''))
                  }
                  placeholder="CUSTOM_ROLE"
                  className="w-full px-3 py-2 text-caption bg-bg-elevated border border-stroke rounded-md text-fg placeholder-fg-disabled focus:border-color-accent focus:outline-none font-mono"
                />
                <p className="text-caption text-fg-disabled mt-1 font-korean">
                  영문 대문자, 숫자, 언더스코어만 허용 (생성 후 변경 불가)
                </p>
              </div>
              <div>
                <label className="text-label-2 text-fg-disabled font-korean block mb-1">
                  역할 이름
                </label>
                <input
                  type="text"
                  value={newRoleName}
                  onChange={(e) => setNewRoleName(e.target.value)}
                  placeholder="사용자 정의 역할"
                  className="w-full px-3 py-2 text-caption bg-bg-elevated border border-stroke rounded-md text-fg placeholder-fg-disabled focus:border-color-accent focus:outline-none font-korean"
                />
              </div>
              <div>
                <label className="text-label-2 text-fg-disabled font-korean block mb-1">
                  설명 (선택)
                </label>
                <input
                  type="text"
                  value={newRoleDesc}
                  onChange={(e) => setNewRoleDesc(e.target.value)}
                  placeholder="역할에 대한 설명"
                  className="w-full px-3 py-2 text-caption bg-bg-elevated border border-stroke rounded-md text-fg placeholder-fg-disabled focus:border-color-accent focus:outline-none font-korean"
                />
              </div>
              {createError && (
                <div className="px-3 py-2 text-label-2 text-color-danger bg-[rgba(239,68,68,0.08)] border border-[rgba(239,68,68,0.2)] rounded-md font-korean">
                  {createError}
                </div>
              )}
            </div>
            <div className="px-5 py-3 border-t border-stroke flex justify-end gap-2">
              <button
                onClick={() => setShowCreateForm(false)}
                className="px-4 py-2 text-caption text-fg-disabled border border-stroke rounded-md hover:bg-bg-surface-hover font-korean"
              >
                취소
              </button>
              <button
                onClick={handleCreateRole}
                disabled={!newRoleCode || !newRoleName || creating}
                className="px-4 py-2 text-caption font-semibold rounded-md bg-color-accent text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)] transition-all font-korean disabled:opacity-50"
              >
                {creating ? '생성 중...' : '생성'}
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}
