// background.js - 完全版（タブ遷移後の再注入対応）

const EVALIGN_URL = 'https://www.evalign.fun/';
const DOWNLOAD_TIMEOUT_MS = 30000;

// ===== メッセージ受信 =====
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === 'START_FLOW') {
    sendResponse({ ok: true });
    startFlow(msg.tabId).catch(err => {
      console.error('[background] startFlow失敗:', err);
      notify('エラー', err.message || String(err));
    });
    return false;
  }

  if (msg.type === 'NAVIGATE_TO_GRADING') {
    // content_moodle.js から「提出ビューへ遷移してほしい」依頼
    const tabId = sender.tab && sender.tab.id;
    if (tabId) {
      console.log('[background] 提出ビューへ遷移:', msg.url);
      navigateAndReinject(tabId, msg.url).catch(err => {
        console.error('[background] 遷移後の再注入失敗:', err);
        notify('エラー', '提出ビュー遷移後の処理に失敗: ' + err.message);
      });
    }
    return false;
  }

  if (msg.type === 'EVALIGN_READY') {
    chrome.storage.local.get(['csvFile'], (data) => {
      sendResponse({ csvFile: data.csvFile || null });
    });
    return true;
  }

  if (msg.type === 'EVALIGN_DONE') {
    notify('完了', 'evalign.fun へのファイルセットが完了しました。');
    chrome.storage.local.remove(['csvFile']);
    return false;
  }

  if (msg.type === 'EVALIGN_ERROR') {
    notify('エラー', 'evalign.fun でのアップロード設定に失敗: ' + msg.error);
    return false;
  }

  return false;
});

// ===== メイン処理 =====
async function startFlow(tabId) {
  await chrome.storage.local.remove(['csvFile']);

  // ダウンロード監視を先に登録（遷移をまたいでも有効）
  const downloadPromise = waitForDownload();

  // content script を注入
  await chrome.scripting.executeScript({
    target: { tabId },
    files: ['content_moodle.js']
  });

  await sleep(300);

  // Moodle操作を依頼
  chrome.tabs.sendMessage(tabId, { type: 'MOODLE_DOWNLOAD' }, (resp) => {
    if (chrome.runtime.lastError) {
      console.warn('[background] Moodleタブ応答エラー:', chrome.runtime.lastError.message);
    } else {
      console.log('[background] Moodle応答:', resp);
    }
  });

  // ダウンロード完了を待機
  let downloadItem;
  try {
    downloadItem = await downloadPromise;
  } catch (e) {
    notify('エラー', 'CSVのダウンロードに失敗しました: ' + e.message);
    throw e;
  }

  await saveDownloadedFile(downloadItem);
  await chrome.tabs.create({ url: EVALIGN_URL, active: true });
  notify('進行中', 'evalign.fun を開きました。ファイルを自動セットします...');
}

// ===== タブ遷移 → 完了待ち → 再注入 =====
async function navigateAndReinject(tabId, url) {
  // 遷移完了を待つPromise
  const navDone = waitForTabComplete(tabId);

  // タブを遷移させる
  await chrome.tabs.update(tabId, { url });

  // 遷移完了待ち
  await navDone;
  // 念のためDOM描画を少し待つ
  await sleep(800);

  // content script を再注入
  await chrome.scripting.executeScript({
    target: { tabId },
    files: ['content_moodle.js']
  });

  await sleep(300);

  // 再度ダウンロード操作を依頼
  chrome.tabs.sendMessage(tabId, { type: 'MOODLE_DOWNLOAD' }, (resp) => {
    if (chrome.runtime.lastError) {
      console.warn('[background] 再注入後の応答エラー:', chrome.runtime.lastError.message);
    } else {
      console.log('[background] 再注入後のMoodle応答:', resp);
    }
  });
}

// タブ読み込み完了を待つ
function waitForTabComplete(tabId) {
  return new Promise((resolve) => {
    function listener(updatedTabId, changeInfo) {
      if (updatedTabId === tabId && changeInfo.status === 'complete') {
        chrome.tabs.onUpdated.removeListener(listener);
        resolve();
      }
    }
    chrome.tabs.onUpdated.addListener(listener);

    // 念のため15秒でタイムアウト
    setTimeout(() => {
      chrome.tabs.onUpdated.removeListener(listener);
      resolve();
    }, 15000);
  });
}

// ===== ダウンロード監視 =====
function waitForDownload() {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      cleanup();
      reject(new Error('ダウンロード待機タイムアウト（30秒）'));
    }, DOWNLOAD_TIMEOUT_MS);

    let trackingId = null;

    function isCsvLike(item) {
      const fname = (item.filename || '').toLowerCase();
      const mime = (item.mime || '').toLowerCase();
      const url = (item.url || '').toLowerCase();
      const finalUrl = (item.finalUrl || '').toLowerCase();
      return (
        fname.endsWith('.csv') ||
        mime.includes('csv') ||
        mime.includes('excel') ||
        mime.includes('octet-stream') ||
        url.includes('csv') ||
        url.includes('downloadgrades') ||
        finalUrl.includes('downloadgrades') ||
        url.includes('grading')
      );
    }

    function onCreated(item) {
      if (trackingId === null && isCsvLike(item)) {
        trackingId = item.id;
        console.log('[background] ダウンロード追跡開始 id=', trackingId);
      }
    }

    function onChanged(delta) {
      if (trackingId === null) {
        if (delta.state && delta.state.current === 'complete') {
          chrome.downloads.search({ id: delta.id }, (results) => {
            if (!results || !results[0]) return;
            if (isCsvLike(results[0])) {
              cleanup();
              resolve(results[0]);
            }
          });
        }
        return;
      }

      if (delta.id !== trackingId) return;

      if (delta.state && delta.state.current === 'complete') {
        chrome.downloads.search({ id: trackingId }, (results) => {
          cleanup();
          if (results && results[0]) resolve(results[0]);
          else reject(new Error('完了したダウンロード情報が取得できません'));
        });
      } else if (delta.state && delta.state.current === 'interrupted') {
        cleanup();
        reject(new Error('ダウンロードが中断されました'));
      }
    }

    function cleanup() {
      clearTimeout(timer);
      chrome.downloads.onCreated.removeListener(onCreated);
      chrome.downloads.onChanged.removeListener(onChanged);
    }

    chrome.downloads.onCreated.addListener(onCreated);
    chrome.downloads.onChanged.addListener(onChanged);
  });
}

// ===== ダウンロードファイルを保存 =====
async function saveDownloadedFile(item) {
  let blob;
  try {
    const fetchUrl = item.finalUrl || item.url;
    const res = await fetch(fetchUrl, { credentials: 'include' });
    if (!res.ok) throw new Error('HTTP ' + res.status);
    blob = await res.blob();
  } catch (e) {
    throw new Error('ダウンロード元URLの再取得に失敗: ' + e.message);
  }

  const base64 = await blobToBase64(blob);
  const filename = extractBasename(item.filename) || 'gradingworksheet.csv';

  await chrome.storage.local.set({
    csvFile: {
      name: filename,
      type: blob.type || 'text/csv',
      base64: base64,
      timestamp: Date.now()
    }
  });
  console.log('[background] CSV保存完了:', filename, 'size=', blob.size);
}

function blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result;
      const idx = result.indexOf(',');
      resolve(result.substring(idx + 1));
    };
    reader.onerror = () => reject(reader.error);
    reader.readAsDataURL(blob);
  });
}

function extractBasename(p) {
  if (!p) return '';
  return p.split(/[\\/]/).pop();
}

function sleep(ms) {
  return new Promise(r => setTimeout(r, ms));
}

function notify(title, message) {
  try {
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icon48.png',
      title: title,
      message: message
    });
  } catch (e) {
    console.log('[notify]', title, message);
  }
}
