{# 경로/파일: realcom-nas-ui/templates/disk.html #}
{% extends "base.html" %}
{% block title %}디스크 관리 - 리얼컴 NAS UI{% endblock %}

{% block head %}
<style>
  table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
  }
  th, td {
    border: 1px solid #ddd;
    padding: 6px 8px;
    text-align: center;
  }
  th {
    background: #f3f6f9;
    font-weight: bold;
  }
  .warning { color: #dc2626; font-weight: bold; }
  .btn {
    padding: 4px 8px;
    font-size: 12px;
    margin: 0 2px;
    cursor: pointer;
  }
  .badge {
    display: inline-block;
    padding: 2px 6px;
    font-size: 12px;
    border-radius: 6px;
    background: #eef2ff;
    border: 1px solid #c7d2fe;
    color: #3730a3;
    margin-left: 6px;
    white-space: nowrap;
  }
  .badge-ok {
    background: #ecfdf5;
    border-color: #a7f3d0;
    color: #065f46;
  }
  .badge-bad {
    background: #fef2f2;
    border-color: #fecaca;
    color: #991b1b;
  }
  .badge-warn {
    background: #fffbeb;
    border-color: #fde68a;
    color: #92400e;
  }
  .muted { color: #6b7280; font-size: 12px; }
  .row-actions {
    display: flex;
    gap: 4px;
    justify-content: center;
    flex-wrap: wrap;
  }
  .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
  .left { text-align: left; }
  .nowrap { white-space: nowrap; }
  .chip {
    display:inline-flex; align-items:center; gap:6px;
    padding: 4px 8px;
    background:#fafafa;
    border:1px solid #eee;
    border-radius: 10px;
  }
  .spacer { height: 8px; }

  /* =========================
     ✅ 자동마운트 토글 UI
     ========================= */
  .am-wrap{
    display:flex; align-items:center; justify-content:space-between;
    gap:16px; padding:12px 14px; margin:10px 0 14px;
    background:#fff; border:1px solid #e6eaf0; border-radius:12px;
    box-shadow:0 2px 10px rgba(20,30,55,.04);
  }
  .am-title{ font-weight:800; font-size:14px; }
  .am-toggle{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
  .am-pill{
    position:relative; width:150px; height:36px;
    border-radius:999px; background:#f3f6fb; border:1px solid #e2e8f0;
    display:flex; overflow:hidden;
  }
  .am-btn{
    flex:1; border:0; background:transparent; cursor:pointer;
    font-weight:800; font-size:13px; z-index:2;
  }
  .am-knob{
    position:absolute; top:3px; left:3px;
    width:72px; height:30px; border-radius:999px;
    background:#111827; transition:all .18s ease;
    box-shadow:0 6px 18px rgba(0,0,0,.18);
  }
  .am-toggle[data-enabled="1"] .am-knob{ left:75px; }
  .am-toggle[data-enabled="0"] .am-off{ color:#fff; }
  .am-toggle[data-enabled="1"] .am-on{ color:#fff; }
  .am-toggle[data-enabled="0"] .am-on{ color:#475569; }
  .am-toggle[data-enabled="1"] .am-off{ color:#475569; }
  .am-desc{ font-size:12px; color:#64748b; white-space:nowrap; }

  @media (max-width: 820px){
    .am-wrap{ flex-direction:column; align-items:flex-start; }
    .am-desc{ white-space:normal; }
  }
</style>
{% endblock %}

{% block content %}
<h2>디스크 관리</h2>

<p class="warning">
  ⚠️ 포맷 전에 반드시 해당 파티션을 언마운트하세요.<br/>
  시스템이 사용 중인 파티션은 포맷이 실패할 수 있습니다.
</p>

<!-- =========================
     ✅ 자동마운트 토글 UI
     - 기본 OFF
     - ON이면 마운트 경로 입력 무시하고 /mnt/usb|hdd|nvme/모델+용량(-n) 자동 생성
     ========================= -->
<div class="am-wrap">
  <div class="am-title">자동 마운트</div>

  <div class="am-toggle" id="amToggle" data-enabled="0">
    <div class="am-pill">
      <button type="button" class="am-btn am-off" id="amOff">OFF</button>
      <button type="button" class="am-btn am-on" id="amOn">ON</button>
      <div class="am-knob" id="amKnob"></div>
    </div>
    <div class="am-desc" id="amDesc">불러오는 중...</div>
  </div>
</div>

<div style="margin: 10px 0; padding: 10px; border: 1px solid #eee; background: #fafafa; border-radius: 8px;">
  <div style="display:flex; align-items:center; gap:10px; flex-wrap:wrap;">
    <strong>현재 공유파일 탐색기 기본 폴더 (1개)</strong>
    <span id="elfinder-current" class="muted">불러오는 중...</span>
    <button class="btn" type="button" onclick="fetchElfinderConfig()">새로고침</button>
  </div>
  <div class="muted" style="margin-top:6px;">
    여기서 설정하면 <b>connector.minimal.php</b> 수정 없이 공유파일 탐색기가 이 경로로 붙도록 만들 수 있음.
    <div class="spacer"></div>

    <div class="chip">
      <span class="muted">정책 허용 루트:</span>
      <span class="mono">/mnt/storage, /mnt/tmp, /mnt/usb*, /mnt/usb, /mnt/hdd, /mnt/nvme</span>
    </div>

    <!-- ✅ /media 자동마운트 경고 -->
    <div class="chip" style="margin-left:6px;">
      <span class="muted">주의:</span>
      <span class="mono">/media/* 자동마운트는 공유파일 탐색기 등록 불가</span>
    </div>

    <div class="chip" style="margin-left:6px;">
      <span class="muted">OS 루트 디스크:</span>
      <span>보호 모드(등록 버튼 숨김)</span>
    </div>

    <div class="spacer"></div>
    <div class="muted">
      ※ 현재 버전은 공유파일 탐색기 기본 폴더 <b>1개만</b> 지원 (새 설정 저장 시 기존 값은 덮어씀)
    </div>
  </div>
</div>

<table>
  <thead>
    <tr>
      <th>장치</th>
      <th>마운트</th>
      <th>FS</th>
      <th>전체용량</th>
      <th>사용량</th>
      <th>남은용량</th>
      <th>사용률(%)</th>
      <th>SMART 상태</th>
      <th>온도(℃)</th>
      <th>공유파일 탐색기</th>
      <th>관리</th>
    </tr>
  </thead>
  <tbody id="disk-table-body">
    <tr><td colspan="11">로딩 중...</td></tr>
  </tbody>
</table>

<script>
  // =========================
  // 상태
  // =========================
  let ELFINDER_CONFIG = null; // { roots: [...] }
  let AUTOMOUNT_ENABLED = false;

  // =========================
  // 유틸
  // =========================
  function escHtml(s) {
    return String(s ?? '').replace(/[&<>"']/g, (c) => ({
      '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#39;'
    }[c]));
  }

  function normPath(p) {
    return String(p || '').replace(/\/+$/, '');
  }

  function getTempClass(temp) {
    const t = Number(temp);
    if (!Number.isFinite(t)) return '';
    if (t >= 55) return 'warning';
    if (t >= 40) return '';
    return '';
  }

  function smartBadgeHtml(status) {
    const s = String(status || '');
    if (s === '정상') return `<span class="badge badge-ok">SMART 정상</span>`;
    if (s === '오류') return `<span class="badge badge-bad">SMART 오류</span>`;
    if (s === '지원안함') return `<span class="badge badge-warn">SMART 지원안함</span>`;
    if (!s) return `<span class="badge badge-warn">SMART 알수없음</span>`;
    return `<span class="badge badge-warn">SMART ${escHtml(s)}</span>`;
  }

  // =========================
  // ✅ 자동마운트 토글 (GET/POST)
  // =========================
  function setAutomountUI(enabled) {
    AUTOMOUNT_ENABLED = !!enabled;
    const el = document.getElementById('amToggle');
    el.setAttribute('data-enabled', enabled ? "1" : "0");
    document.getElementById('amDesc').textContent =
      enabled
        ? "ON: /mnt/usb|hdd|nvme/모델+용량(-n) 자동 생성 (입력 무시)"
        : "OFF: 사용자가 입력한 마운트 경로로 마운트";
  }

  async function fetchAutomount() {
    try {
      const r = await fetch('/api/automount', { headers: { 'Accept': 'application/json' }});
      const j = await r.json();
      setAutomountUI(!!(j && j.enabled));
    } catch (e) {
      // 실패해도 기본 OFF로 둠
      setAutomountUI(false);
    }
  }

  async function setAutomount(enabled) {
    try {
      const body = new URLSearchParams();
      body.set('enabled', enabled ? 'true' : 'false');

      const r = await fetch('/api/automount', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Accept': 'application/json'
        },
        body
      });

      const j = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(j.error || `서버 오류 (HTTP ${r.status})`);
      setAutomountUI(!!j.enabled);
    } catch (e) {
      alert('자동마운트 설정 실패: ' + (e.message || e));
    }
  }

  // =========================
  // 서버 액션(기존 /disk POST 유지)
  // =========================
  async function postDiskAction(data) {
    try {
      const res = await fetch('/disk', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Accept': 'application/json',
          'X-Requested-With': 'fetch'
        },
        body: new URLSearchParams(data)
      });

      const out = await res.json().catch(() => ({}));

      if (!res.ok || out.ok === false) {
        throw new Error(out.error || `서버 오류 (HTTP ${res.status})`);
      }

      // 서버가 automount_enabled 내려주면 즉시 반영
      if (typeof out.automount_enabled !== 'undefined') {
        setAutomountUI(!!out.automount_enabled);
      }

      alert(out.message || '작업이 완료되었습니다.');

      if (out.disks) {
        renderDisks(out.disks);
      } else {
        await fetchDisks();
      }
    } catch (e) {
      alert(`오류 발생: ${e.message}`);
    }
  }

  // =========================
  // elFinder 설정 읽기/표시
  // =========================
  function elfinderText(conf) {
    if (!conf || !Array.isArray(conf.roots) || conf.roots.length === 0) return "설정 없음";
    return conf.roots.map((r, idx) => {
      const alias = r?.alias ? `[${r.alias}] ` : '';
      const p = r?.path || '-';
      const u = r?.url ? ` / url=${r.url}` : '';
      return `${idx+1}) ${alias}path=${p}${u}`;
    }).join(" | ");
  }

  async function fetchElfinderConfig() {
    const el = document.getElementById("elfinder-current");
    try {
      const res = await fetch("/api/elfinder/config");
      if (!res.ok) throw new Error("설정 조회 실패");
      const conf = await res.json();
      ELFINDER_CONFIG = conf;
      el.textContent = elfinderText(conf);
    } catch (e) {
      el.textContent = `오류: ${e.message}`;
      ELFINDER_CONFIG = null;
    }
  }

  function isCurrentElfinderRoot(mountpointReal) {
    if (!mountpointReal || !ELFINDER_CONFIG || !Array.isArray(ELFINDER_CONFIG.roots) || ELFINDER_CONFIG.roots.length === 0) return false;
    const mp = normPath(mountpointReal);
    return ELFINDER_CONFIG.roots.some(r => normPath(r?.path || '') === mp);
  }

  // =========================
  // elFinder 루트 설정
  // =========================
  async function setElfinderRoot(mountpointReal, suggestedAlias, currentAlias) {
    const mp = String(mountpointReal || '').trim();
    if (!mp) {
      alert("마운트된 디스크만 공유파일 탐색기 기본 폴더로 지정할 수 있습니다.");
      return;
    }

    const curRoot0 = (ELFINDER_CONFIG?.roots?.[0]) || {};
    const defaultAlias = (String(currentAlias || '').trim())
      || (String(suggestedAlias || '').trim())
      || (String(curRoot0.alias || '').trim())
      || (mp.split("/").filter(Boolean).pop() || "DATA");

    const curUrl = (curRoot0.url && String(curRoot0.url).trim()) ? String(curRoot0.url).trim() : "";

    const alias = prompt("공유파일 탐색기에 표시될 이름(alias)", defaultAlias);
    if (alias === null) return;
    const aliasTrim = String(alias).trim();
    if (!aliasTrim) {
      alert("alias는 비워둘 수 없습니다.");
      return;
    }

    const url = prompt("웹 URL(선택) - 비워두면 로컬 경로만 사용", curUrl);
    if (url === null) return;
    const urlTrim = String(url).trim();

    const root = { alias: aliasTrim, path: mp };
    if (urlTrim) root.url = urlTrim;

    try {
      const res = await fetch("/api/elfinder/config", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ roots: [root] })
      });

      const out = await res.json().catch(() => ({}));
      if (!res.ok) throw new Error(out.error || "저장 실패");

      alert("공유파일 탐색기 기본 폴더 저장 완료. 공유파일 탐색기 새로고침하면 반영됨.");

      await fetchElfinderConfig();
      await fetchDisks();

    } catch (e) {
      alert("오류: " + (e?.message || e));
    }
  }

  // =========================
  // 렌더링
  // =========================
  function renderDisks(disks) {
    const tbody = document.getElementById('disk-table-body');
    tbody.innerHTML = '';

    if (!Array.isArray(disks) || disks.length === 0) {
      tbody.innerHTML = '<tr><td colspan="11">디스크 정보가 없습니다.</td></tr>';
      return;
    }

    disks.forEach(disk => {
      const trDisk = document.createElement('tr');

      const isRootDisk = !!disk.is_os_root_disk;
      const diskAllowed = !!disk.is_allowed_root;
      const diskReg = !!disk.is_elfinder_registered;

      const diskMount = disk.mountpoint || '-';
      const diskMountReal = disk.mountpoint_real || '';

      const allowedBadge = diskMountReal
        ? (diskAllowed ? `<span class="badge badge-ok">허용</span>` : `<span class="badge badge-bad">비허용</span>`)
        : `<span class="badge badge-warn">마운트 없음</span>`;

      const rootBadge = isRootDisk ? `<span class="badge badge-warn">OS 루트</span>` : '';

      const elfinderBadge = diskReg
        ? `<span class="badge badge-ok">등록됨</span><span class="badge">${escHtml(disk.elfinder_alias || '')}</span>`
        : `<span class="badge badge-warn">미등록</span>`;

      trDisk.innerHTML = `
        <td class="nowrap"><strong>${escHtml(disk.name)}</strong> ${rootBadge}</td>

        <!-- 마운트 칸 아래에 모델/용량 표시 -->
        <td class="mono left">
          ${escHtml(diskMount)}
          ${disk.model_info ? `<div class="muted">${escHtml(disk.model_info)}</div>` : ``}
        </td>

        <td>${escHtml(disk.fstype || '-')}</td>
        <td>${escHtml(disk.size || '-')}</td>
        <td>${escHtml(disk.used || '-')}</td>
        <td>${escHtml(disk.avail || '-')}</td>
        <td>${escHtml(disk.percent || '-')}</td>
        <td>${smartBadgeHtml(disk.smart_status)}</td>
        <td class="${getTempClass(disk.temperature)}">${escHtml(disk.temperature ?? '-')}</td>
        <td>${allowedBadge} ${elfinderBadge}</td>
        <td>
          <div class="row-actions">
            <button class="btn" type="button" data-action="smart" data-dev="${escHtml(disk.name)}">SMART</button>
            <button class="btn" type="button" data-action="format-disk" data-dev="${escHtml(disk.name)}">포맷</button>
          </div>
        </td>
      `;
      tbody.appendChild(trDisk);

      // 파티션
      if (Array.isArray(disk.parts) && disk.parts.length > 0) {
        disk.parts.forEach(part => {
          const trPart = document.createElement('tr');

          const pm = part.mountpoint || '';
          const pmReal = part.mountpoint_real || '';

          const allowed = !!part.is_allowed_root;
          const registered = !!part.is_elfinder_registered;

          const isCur = isCurrentElfinderRoot(pmReal);
          const curBadge = isCur ? `<span class="badge">공유파일 탐색기 기본 폴더</span>` : '';

          const allowedBadge2 = pmReal
            ? (allowed ? `<span class="badge badge-ok">허용</span>` : `<span class="badge badge-bad">비허용</span>`)
            : `<span class="badge badge-warn">마운트 없음</span>`;

          const regBadge2 = registered
            ? `<span class="badge badge-ok">등록됨</span><span class="badge">${escHtml(part.elfinder_alias || '')}</span>`
            : `<span class="badge badge-warn">미등록</span>`;

          const canEfinderAction = (!!pmReal) && allowed && !isRootDisk;

          const elfinderActionHtml = canEfinderAction
            ? (registered
                ? `<button class="btn" type="button"
                     data-action="elf-rename"
                     data-path="${escHtml(pmReal)}"
                     data-suggest="${escHtml(part.suggested_alias || '')}"
                     data-cur="${escHtml(part.elfinder_alias || '')}">
                     표시명 변경
                   </button>`
                : `<button class="btn" type="button"
                     data-action="elf-register"
                     data-path="${escHtml(pmReal)}"
                     data-suggest="${escHtml(part.suggested_alias || '')}"
                     data-cur="">
                     공유파일 탐색기 등록
                   </button>`
              )
            : `<span class="muted">
                 ${isRootDisk ? 'OS 루트 보호' : (!pmReal ? '마운트 없음' : (!allowed ? '허용 루트 아님' : '-'))}
               </span>`;

          trPart.innerHTML = `
            <td class="left" style="padding-left: 20px;">
              <span class="mono">↳ /dev/${escHtml(part.name)}</span>
              ${curBadge}
            </td>

            <td class="mono left">
              ${pm ? escHtml(pm) : '<span class="muted">-</span>'}
              ${pmReal ? `<div class="muted mono">${escHtml(pmReal)}</div>` : ''}
              ${part.model_info ? `<div class="muted">${escHtml(part.model_info)}</div>` : ``}
            </td>

            <td>${escHtml(part.fstype || '-')}</td>
            <td>${escHtml(part.size || '-')}</td>
            <td>${escHtml(part.used || '-')}</td>
            <td>${escHtml(part.avail || '-')}</td>
            <td>${escHtml(part.percent || '-')}</td>
            <td>-</td>
            <td>-</td>
            <td>${allowedBadge2} ${regBadge2}</td>
            <td>
              <div class="row-actions">
                <button class="btn" type="button" data-action="mount" data-part="${escHtml(part.name)}">마운트</button>
                <button class="btn" type="button" data-action="umount" data-part="${escHtml(part.name)}">언마운트</button>
                ${elfinderActionHtml}
              </div>
              <div class="row-actions" style="margin-top:6px;">
                <select id="format-${escHtml(part.name)}">
                  <option value="ext4" selected>ext4</option>
                  <option value="vfat">vfat</option>
                  <option value="ntfs">ntfs</option>
                </select>
                <button class="btn" type="button" data-action="format-part" data-part="${escHtml(part.name)}">포맷</button>
              </div>
            </td>
          `;

          tbody.appendChild(trPart);
        });
      }
    });

    // 이벤트 위임
    tbody.querySelectorAll('button[data-action]').forEach(btn => {
      btn.addEventListener('click', (e) => {
        const b = e.currentTarget;
        const act = b.getAttribute('data-action');

        if (act === 'smart') return smartCheck(b.getAttribute('data-dev'));
        if (act === 'format-disk') return formatDisk(b.getAttribute('data-dev'));
        if (act === 'mount') return mountPartition(b.getAttribute('data-part'));
        if (act === 'umount') return unmountPartition(b.getAttribute('data-part'));
        if (act === 'format-part') return formatPartition(b.getAttribute('data-part'));

        if (act === 'elf-register' || act === 'elf-rename') {
          const path = b.getAttribute('data-path') || '';
          const suggest = b.getAttribute('data-suggest') || '';
          const cur = b.getAttribute('data-cur') || '';
          return setElfinderRoot(path, suggest, cur);
        }
      });
    });
  }

  // =========================
  // fetch
  // =========================
  async function fetchDisks() {
    try {
      const res = await fetch('/api/disks');
      if (!res.ok) throw new Error('서버 응답 오류');
      const data = await res.json();
      renderDisks(data);
    } catch (e) {
      const tbody = document.getElementById('disk-table-body');
      tbody.innerHTML = `<tr><td colspan="11">디스크 정보를 불러오는 중 오류가 발생했습니다.<br>${escHtml(e.message)}</td></tr>`;
    }
  }

  // =========================
  // 액션들
  // =========================
  function smartCheck(deviceName) {
    alert(`SMART 상태 확인: ${deviceName} (구현 필요)`);
  }

  function formatDisk(deviceName) {
    if (confirm(`${deviceName} 디스크 전체를 포맷하시겠습니까? 데이터가 모두 삭제됩니다.`)) {
      postDiskAction({ action: 'mkfs', name: deviceName, fstype: 'ext4' });
    }
  }

  function mountPartition(partName) {
    // ✅ 자동마운트 ON이면 경로 입력 없이 바로 mount
    if (AUTOMOUNT_ENABLED) {
      postDiskAction({ action: 'mount', name: partName });
      return;
    }

    const defaultMount = `/mnt/tmp/${partName}`;
    const mountPoint = prompt(
      `${partName} 파티션을 마운트할 경로를 입력하세요.\n` +
      `(허용: /mnt/storage, /mnt/tmp, /mnt/usb*, /mnt/usb/..., /mnt/hdd/..., /mnt/nvme/...)`,
      defaultMount
    );
    if (mountPoint) {
      postDiskAction({ action: 'mount', name: partName, mountpoint: mountPoint });
    }
  }

  function unmountPartition(partName) {
    if (confirm(`${partName} 파티션을 언마운트 하시겠습니까?`)) {
      postDiskAction({ action: 'umount', name: partName });
    }
  }

  function formatPartition(partName) {
    const select = document.getElementById(`format-${partName}`);
    const fsType = select ? select.value : 'ext4';

    // ✅ 자동마운트 ON이어도 포맷+마운트+elFinder는 "니가 지정한 mountpoint"가 더 안전함(실수 방지)
    //    (원하면 여기서도 자동으로 바꿀 수 있는데, 지금은 니 UX 기준으로 유지함)
    const defaultMount = `/mnt/tmp/${partName}`;
    const mountPoint = prompt(
      `${partName} 포맷 후 마운트 경로\n` +
      `(허용: /mnt/storage, /mnt/tmp, /mnt/usb*, /mnt/usb/..., /mnt/hdd/..., /mnt/nvme/...)`,
      defaultMount
    );
    if (!mountPoint) return;

    const alias = prompt("공유파일 탐색기 표시명 (예: DATA)", "DATA");
    if (alias === null) return;

    const webPath = prompt("공유파일 탐색기 web_path (예: data)  ※영문추천", "data");
    if (webPath === null) return;

    if (!confirm(`${partName} 파티션을 ${fsType}로 포맷하고\n${mountPoint}에 마운트한 뒤\n공유파일 탐색기 기본 폴더로 지정할까요?\n(데이터 전부 삭제됨)`)) {
      return;
    }

    postDiskAction({
      action: 'mkfs_mount_elfinder',
      name: partName,
      fstype: fsType,
      mountpoint: mountPoint,
      alias: alias,
      web_path: webPath
    });
  }

  // =========================
  // 초기 로드
  // =========================
  (async () => {
    // 토글 상태 먼저 읽기
    await fetchAutomount();

    // 토글 버튼 이벤트
    document.getElementById('amOff').addEventListener('click', () => setAutomount(false));
    document.getElementById('amOn').addEventListener('click', () => setAutomount(true));

    await fetchElfinderConfig();
    await fetchDisks();
    setInterval(fetchDisks, 10000);
  })();
</script>
{% endblock %}
