<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>入退室記録アプリ ver 1.3</title>
  <script type="module">
    import { initializeApp } from "https://www.gstatic.com/firebasejs/10.13.2/firebase-app.js";
    import { 
      getDatabase, ref, push, query, limitToLast, onChildAdded, off, set, get, onValue, orderByChild, equalTo 
    } from "https://www.gstatic.com/firebasejs/10.13.2/firebase-database.js";
    import { getAuth, signInWithEmailAndPassword, signOut, onAuthStateChanged } from "https://www.gstatic.com/firebasejs/10.13.2/firebase-auth.js";

    const firebaseConfig = {
      apiKey: "AIzaSyAy7776-05AsmDxDG1OXODpuiI05pSTAEg",
      authDomain: "salesio-fes.firebaseapp.com",
      databaseURL: "https://salesio-fes-default-rtdb.firebaseio.com",
      projectId: "salesio-fes",
      storageBucket: "salesio-fes.appspot.com",
      messagingSenderId: "102413045580",
      appId: "1:102413045580:web:14f964e4bc8dfdbfd889e9",
      measurementId: "G-RLBE53FTB1"
    };

    const app = initializeApp(firebaseConfig);
    const database = getDatabase(app);
    const auth = getAuth(app);
    let currentUser = null;
    let timeoutTimer = null;
    let countdownTimer = null;
    const timeoutDuration = 10 * 60 * 1000; // 10分

    // セッション管理用変数
    let sessionId = null;
    let sessionRef = null;
    let sessionInterval = null;

    // セッションID生成（簡易版）
    function generateSessionId() {
      return '_' + Math.random().toString(36).substr(2, 9);
    }

    // セッション開始：詳細情報（ログイン時刻、ユーザーエージェント、最終アクティビティ）を記録
    function startSession(user) {
      sessionId = generateSessionId();
      sessionRef = ref(database, `activeUsers/${user.uid}/${sessionId}`);
      const sessionInfo = {
        user: user.email,
        status: '入室',
        loginTime: Date.now(),
        userAgent: navigator.userAgent,
        lastActivity: Date.now()
      };
      set(sessionRef, sessionInfo);
      // 定期的に最終アクティビティを更新（例：1分ごと）
      sessionInterval = setInterval(updateLastActivity, 60000);
    }

    // 最終アクティビティ更新
    function updateLastActivity() {
      if (currentUser && sessionId) {
        const lastActivityRef = ref(database, `activeUsers/${currentUser.uid}/${sessionId}/lastActivity`);
        set(lastActivityRef, Date.now());
      }
    }

    // セッション終了：セッション情報を「退室」に更新し、タイマーをクリア
    function endSession() {
      if (currentUser && sessionId) {
        const activeUserSessionRef = ref(database, `activeUsers/${currentUser.uid}/${sessionId}`);
        set(activeUserSessionRef, { user: currentUser.email, status: '退室', logoutTime: Date.now() });
      }
      sessionId = null;
      sessionRef = null;
      if (sessionInterval) {
        clearInterval(sessionInterval);
        sessionInterval = null;
      }
    }

    // タイムアウト処理
    function startTimeout() {
      let remainingTime = timeoutDuration;
      updateCountdown(remainingTime);
      countdownTimer = setInterval(() => {
        remainingTime -= 1000;
        updateCountdown(remainingTime);
        if (remainingTime <= 0) {
          clearInterval(countdownTimer);
        }
      }, 1000);
      timeoutTimer = setTimeout(async () => {
        // タイムアウト時、セッション情報を更新してログアウト
        if (currentUser && sessionId) {
          const activeUserSessionRef = ref(database, `activeUsers/${currentUser.uid}/${sessionId}`);
          await set(activeUserSessionRef, { user: currentUser.email, status: '退室', logoutTime: Date.now() });
        }
        await signOut(auth);
        alert("タイムアウトしました。自動的にログアウトされます。");
        clearInterval(countdownTimer);
      }, timeoutDuration);
    }

    // 残り時間表示更新
    function updateCountdown(remainingTime) {
      const countdownElement = document.getElementById('countdown');
      const minutes = Math.floor(remainingTime / 60000);
      const seconds = Math.floor((remainingTime % 60000) / 1000);
      countdownElement.textContent = `残り時間: ${minutes}分 ${seconds}秒`;
    }

    // 入退室記録の保存
    function saveRecord(grade, group, number, name, status) {
      const time = new Date().toLocaleString();
      const newRecord = { grade, group, number, name, status, time, user: currentUser.email };
      const recordsRef = ref(database, 'records');
      push(recordsRef, newRecord)
        .then(() => {
          alert(`${grade}${group}${number}（${name}）の${status}が記録されました！`);
        })
        .catch((error) => {
          alert("記録に失敗しました: " + error.message);
        });
    }

    // 退室記録の場合、最新の入室レコードを探して記録
    async function checkAndRecordExit(name) {
      const recordsRef = ref(database, 'records');
      const snapshot = await get(recordsRef);
      let latestEntry = null;
      snapshot.forEach(childSnapshot => {
        const record = childSnapshot.val();
        if (record.name === name && record.status === "入室") {
          if (!latestEntry || new Date(record.time) > new Date(latestEntry.time)) {
            latestEntry = record;
          }
        }
      });
      if (latestEntry) {
        saveRecord(latestEntry.grade, latestEntry.group, latestEntry.number, name, "退室");
      } else {
        alert("入室記録がありません。やり直してください。");
      }
    }

    // 最新10件のログをリアルタイムで表示（リスナー登録・解除）
    let recentLogsQuery;
    let handleNewLog;
    function listenToRecentLogs() {
      const recordsRef = ref(database, 'records');
      if(recentLogsQuery && handleNewLog){
        off(recentLogsQuery, "child_added", handleNewLog);
      }
      recentLogsQuery = query(recordsRef, limitToLast(10));
      const logList = document.getElementById('logList');
      logList.innerHTML = "";
      handleNewLog = (snapshot) => {
        const record = snapshot.val();
        const listItem = document.createElement('li');
        listItem.textContent = `${record.time} - ${record.grade}${record.group}${record.number} ${record.name} ${record.status}`;
        logList.insertBefore(listItem, logList.firstChild);
        while (logList.childNodes.length > 10) {
          logList.removeChild(logList.lastChild);
        }
      };
      onChildAdded(recentLogsQuery, handleNewLog);
    }

    // シークレットキー検出（キー列「a」「d」「m」「i」「n」）と名前検索
    let secretKeySequence = ['a', 'd', 'm', 'i', 'n'];
    let inputSequence = [];
    document.addEventListener('keydown', (e) => {
      inputSequence.push(e.key);
      if (inputSequence.length > secretKeySequence.length) {
        inputSequence.shift();
      }
      if (inputSequence.join('') === secretKeySequence.join('')) {
        inputSequence = [];
        const nameToSearch = prompt("名前を入力してください:");
        if (nameToSearch) {
          const recordsRef = ref(database, 'records');
          const q = query(recordsRef, orderByChild("name"), equalTo(nameToSearch));
          get(q)
            .then((snapshot) => {
              if (snapshot.exists()) {
                let ids = [];
                snapshot.forEach(childSnapshot => {
                  ids.push(childSnapshot.key);
                });
                alert("識別ID: " + ids.join(', '));
              } else {
                alert("その名前の記録は見つかりませんでした。");
              }
            })
            .catch((error) => {
              alert("エラーが発生しました: " + error.message);
            });
        }
      }
    });

    document.addEventListener('DOMContentLoaded', () => {
      const formEntry = document.getElementById('attendanceFormEntry');
      const formExit = document.getElementById('attendanceFormExit');
      const loginForm = document.getElementById('loginForm');
      const logoutButton = document.getElementById('logoutButton');
      const countdownElement = document.getElementById('countdown');

      // ログインフォーム送信時
      loginForm.addEventListener('submit', async (event) => {
        event.preventDefault();
        const email = document.getElementById('email').value;
        const password = document.getElementById('password').value;
        try {
          await signInWithEmailAndPassword(auth, email, password);
          alert("ログイン成功！");
          loginForm.reset();
          startTimeout();
        } catch (error) {
          alert("ログインに失敗しました: " + error.message);
        }
      });

      // ログアウトボタン処理
      logoutButton.addEventListener('click', async () => {
        try {
          // セッションごとの情報を「退室」に更新
          endSession();
          const activeUserRef = ref(database, 'activeUsers/' + currentUser.uid);
          // ※ 複数セッションがある場合、他のセッションはそのまま残るので注意
          await signOut(auth);
          alert("ログアウトしました。");
          clearInterval(countdownTimer);
          if(recentLogsQuery && handleNewLog){
            off(recentLogsQuery, "child_added", handleNewLog);
          }
        } catch (error) {
          alert("ログアウトに失敗しました: " + error.message);
        }
      });

      // 認証状態監視
      onAuthStateChanged(auth, (user) => {
        if (user) {
          currentUser = user;
          formEntry.style.display = 'block';
          formExit.style.display = 'block';
          loginForm.style.display = 'none';
          logoutButton.style.display = 'block';
          countdownElement.style.display = 'block';
          // セッション開始：詳細情報を記録
          startSession(user);
          // activeUsers にログイン状態を記録（この場合はセッション情報としてすでに記録済み）
          const activeUserRef = ref(database, 'activeUsers/' + currentUser.uid);
          set(activeUserRef, { user: currentUser.email, status: '入室', loginTime: Date.now() });
          // 管理者による強制ログアウトの監視
          onValue(activeUserRef, (snapshot) => {
            const data = snapshot.val();
            if (data && data.status === '強制ログアウト') {
              alert("管理者によってログアウトされました");
              signOut(auth);
              formEntry.style.display = 'none';
              formExit.style.display = 'none';
              loginForm.style.display = 'block';
              logoutButton.style.display = 'none';
              countdownElement.style.display = 'none';
              clearInterval(countdownTimer);
              if(recentLogsQuery && handleNewLog){
                off(recentLogsQuery, "child_added", handleNewLog);
              }
            }
          });
          listenToRecentLogs();
        } else {
          currentUser = null;
          formEntry.style.display = 'none';
          formExit.style.display = 'none';
          loginForm.style.display = 'block';
          logoutButton.style.display = 'none';
          countdownElement.style.display = 'none';
          clearInterval(countdownTimer);
          endSession();
          if(recentLogsQuery && handleNewLog){
            off(recentLogsQuery, "child_added", handleNewLog);
          }
        }
      });

      // 入室フォーム送信
      formEntry.addEventListener('submit', (event) => {
        event.preventDefault();
        const grade = document.getElementById('grade').value;
        const group = document.getElementById('group').value;
        const number = document.getElementById('number').value;
        const name = document.getElementById('nameEntry').value;
        saveRecord(grade, group, number, name, "入室");
        formEntry.reset();
      });

      // 退室フォーム送信
      formExit.addEventListener('submit', (event) => {
        event.preventDefault();
        const name = document.getElementById('nameExit').value;
        checkAndRecordExit(name);
        formExit.reset();
      });

      // ページ終了時の処理
      window.addEventListener('beforeunload', async (event) => {
        if (currentUser) {
          endSession();
          const activeUserRef = ref(database, 'activeUsers/' + currentUser.uid);
          set(activeUserRef, { user: currentUser.email, status: '退室', logoutTime: Date.now() });
          await signOut(auth);
          currentUser = null;
          if(recentLogsQuery && handleNewLog){
            off(recentLogsQuery, "child_added", handleNewLog);
          }
        }
      });
    });
  </script>
</head>
<body>
  <h1>入退室記録アプリ</h1>
  <h2>ログイン</h2>
  <form id="loginForm">
    <label for="email">メールアドレス:</label>
    <input type="email" id="email" required>
    <label for="password">パスワード:</label>
    <input type="password" id="password" required>
    <button type="submit">ログイン</button>
  </form>
  <button id="logoutButton" style="display:none;">ログアウト</button>
  <div id="countdown" style="display:none;">残り時間: 5分 0秒</div>
  <div style="display: flex;">
    <!-- 左側：入退室記録フォーム -->
    <div>
      <h2>入室記録（名字と名前の間にスペースは入れない）</h2>
      <form id="attendanceFormEntry" style="display:none;">
        <select id="grade" required>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
          <option value="4">4</option>
          <option value="5">5</option>
          <option value="6">6</option>
        </select>
        <label for="grade">年</label>
        <select id="group" required>
          <option value="A">A</option>
          <option value="B">B</option>
          <option value="C">C</option>
          <option value="D">D</option>
        </select>
        <label for="group">組</label>
        <input type="text" id="number" placeholder="番号（例: 01）" pattern="\d{2}" maxlength="2" required title="2桁の番号（01~46）を入力してください">
        <input type="text" id="nameEntry" placeholder="名前" required>
        <button type="submit">記録</button>
      </form>
      <h2>退室記録（名字と名前の間にスペースは入れない）</h2>
      <form id="attendanceFormExit" style="display:none;">
        <input type="text" id="nameExit" placeholder="名前" required>
        <button type="submit">記録</button>
      </form>
    </div>
    <!-- 右側：最近のログ表示 -->
    <div>
      <h2>最近のログ</h2>
      <ul id="logList"></ul>
    </div>
  </div>
</body>
</html>
