// GuardRAIl Test Bridge - Injected into page context
// This file runs in the page's window context (not isolated content script world)

(function() {
  if (window.guardrailTest) return;
  
  // Create methods that communicate with content script via custom events
  window.guardrailTest = {
    testClassification: function(prompt, options) {
      return new Promise((resolve, reject) => {
        const eventId = 'guardrail_' + Date.now() + '_' + Math.random();
        
        const handler = (e) => {
          if (e.detail && e.detail.id === eventId) {
            document.removeEventListener('guardrailResponse', handler);
            if (e.detail.error) {
              reject(new Error(e.detail.error));
            } else {
              resolve(e.detail.result);
            }
          }
        };
        
        document.addEventListener('guardrailResponse', handler);
        
        document.dispatchEvent(new CustomEvent('guardrailRequest', {
          detail: { id: eventId, action: 'testClassification', prompt, options: options || {} },
          bubbles: true
        }));
        
        // Timeout after 30 seconds
        setTimeout(() => {
          document.removeEventListener('guardrailResponse', handler);
          reject(new Error('Timeout waiting for response'));
        }, 30000);
      });
    },
    
    batchTest: async function(prompts, options) {
      return await this._callContentScript('batchTest', { prompts: prompts, options: options }, 300000); // 5 min timeout
    },
    
    validateSystem: async function() {
      return await this._callContentScript('validateSystem', {}, 60000); // 1 min timeout
    },
    
    test200Examples: async function() {
      return await this._callContentScript('test200Examples', {}, 600000); // 10 min timeout for 500 prompts
    },
    
    validateMasterTest: async function() {
      return await this._callContentScript('validateMasterTest', {}, 120000); // 2 min timeout
    },

    /** Curated 100 prompts (pre + post-handoff) to refine the rating system. ~$0.01–0.02 with Gemini. */
    runRatingRefinementSuite: async function() {
      return await this._callContentScript('runRatingRefinementSuite', {}, 300000); // 5 min
    },

    /** 30 post-handoff prompts to test and refine GEMINI_POST_HANDOFF_SYSTEM. */
    runPostHandoffRefinementSuite: async function() {
      return await this._callContentScript('runPostHandoffRefinementSuite', {}, 300000); // 5 min
    },

    /** Test isVagueAnswer (reprompting). Single: testVagueAnswer("idk"). Batch: testVagueAnswer(["idk", "math"]) */
    testVagueAnswer: async function(content) {
      return await this._callContentScript('testVagueAnswer', { content }, 15000);
    },

    /** Run 50 curated vague-answer tests to refine reprompting / isVagueAnswer. */
    runVagueAnswerSuite: async function() {
      return await this._callContentScript('runVagueAnswerSuite', {}, 60000);
    },

    /** Test polishLearningPrompt: 3 answers + original prompt → final learning prompt. Example: guardrailTest.testPolishLearningPrompt("Help with essay", "English", "Compare/contrast essay", "I don't know how to start") */
    testPolishLearningPrompt: async function(originalPrompt, subjectAnswer, taskAnswer, stuckAnswer) {
      return await this._callContentScript('testPolishLearningPrompt', {
        originalPrompt: originalPrompt || '',
        subjectAnswer: subjectAnswer ?? '',
        taskAnswer: taskAnswer ?? '',
        stuckAnswer: stuckAnswer ?? '',
      }, 30000);
    },

    /** Run 20 polish accuracy tests one-by-one (~$0.02). You see each case complete in the console, then get a log. Option: guardrailTest.runPolishAccuracySuite({ download: true }) to auto-save JSON. */
    runPolishAccuracySuite: async function(opts) {
      const runAt = new Date().toISOString();
      const start = Date.now();
      const cases = await this._callContentScript('getPolishAccuracyCases', {}, 5000);
      if (!cases || !cases.length) {
        throw new Error('Could not get polish accuracy cases from extension.');
      }
      console.log('🧪 [page] Running', cases.length, 'polish tests one-by-one...');
      const results = [];
      for (let i = 0; i < cases.length; i++) {
        const c = cases[i];
        const num = i + 1;
        try {
          const r = await this._callContentScript('testPolishLearningPrompt', {
            originalPrompt: c.originalPrompt || '',
            subjectAnswer: c.subjectAnswer ?? '',
            taskAnswer: c.taskAnswer ?? '',
            stuckAnswer: c.stuckAnswer ?? ''
          }, 35000);
          const refined = (r && r.refinedPrompt) ? r.refinedPrompt : '';
          results.push({ index: num, label: c.label, originalPrompt: c.originalPrompt, subjectAnswer: c.subjectAnswer, taskAnswer: c.taskAnswer, stuckAnswer: c.stuckAnswer, refinedPrompt: refined });
          console.log('🧪', num + '/' + cases.length, c.label, refined ? refined.slice(0, 80) + '...' : '');
        } catch (e) {
          results.push({ index: num, label: c.label, originalPrompt: c.originalPrompt, subjectAnswer: c.subjectAnswer, taskAnswer: c.taskAnswer, stuckAnswer: c.stuckAnswer, error: (e && e.message) || String(e) });
          console.warn('🧪', num + '/' + cases.length, c.label, 'ERROR:', (e && e.message) || e);
        }
      }
      const durationMs = Date.now() - start;
      const log = { runAt, durationMs, model: 'gpt-4o-mini', totalCases: results.length, errorCount: results.filter(function(x) { return x.error; }).length, cases: results };
      console.log('🧪 [page] Suite done in', (durationMs / 1000).toFixed(1) + 's', log.errorCount > 0 ? '(' + log.errorCount + ' errors)' : '');
      if (opts && opts.download && log) {
        this.downloadPolishLog(log);
      }
      return log;
    },

    /** 15-case list embedded so suite works even if content script is old (only needs testPolishLearningPrompt). */
    POLISH_ACCURACY_SUITE_15: [
      { originalPrompt: 'How do I find the theme in a poem?', subjectAnswer: 'English', taskAnswer: 'Poetry analysis essay', stuckAnswer: "I don't know how to find theme", label: 'Clear specific' },
      { originalPrompt: 'help me with my homework', subjectAnswer: 'stuff', taskAnswer: 'the assignment', stuckAnswer: 'idk', label: 'Vague fallbacks' },
      { originalPrompt: "What's the derivative of x^2?", subjectAnswer: 'Math', taskAnswer: 'Calculus', stuckAnswer: 'I forgot the power rule', label: 'Subject task clarity' },
      { originalPrompt: 'Write my essay for me', subjectAnswer: '', taskAnswer: '', stuckAnswer: '', label: 'All empty' },
      { originalPrompt: "I'm stuck on this coding problem", subjectAnswer: 'Computer Science', taskAnswer: 'Python project', stuckAnswer: 'Getting a type error', label: 'Technical task' },
      { originalPrompt: 'Explain photosynthesis', subjectAnswer: 'Biology', taskAnswer: 'Lab report', stuckAnswer: 'The light reactions', label: 'Science prior attempt' },
      { originalPrompt: 'Can you just give me the answer?', subjectAnswer: 'Math', taskAnswer: 'Algebra homework', stuckAnswer: 'problem 5', label: 'Shortcut-like' },
      { originalPrompt: "I tried the formula but it's wrong", subjectAnswer: 'Physics', taskAnswer: 'Kinematics', stuckAnswer: 'Which equation to use', label: 'Prior attempt' },
      { originalPrompt: 'idk', subjectAnswer: 'English', taskAnswer: 'Essay', stuckAnswer: 'everything', label: 'All vague' },
      { originalPrompt: 'How do I structure a body paragraph?', subjectAnswer: 'AP Lit', taskAnswer: 'Argument essay', stuckAnswer: 'Topic sentence vs evidence', label: 'AP course' },
      { originalPrompt: 'Why did my loop infinite?', subjectAnswer: 'Programming', taskAnswer: 'Java assignment', stuckAnswer: 'while condition', label: 'Code debug' },
      { originalPrompt: 'help', subjectAnswer: '', taskAnswer: 'math', stuckAnswer: '', label: 'Minimal input' },
      { originalPrompt: 'I need to compare two theories', subjectAnswer: 'Psychology', taskAnswer: 'Research paper', stuckAnswer: 'How to organize', label: 'Research paper' },
      { originalPrompt: 'My teacher said my thesis is weak', subjectAnswer: 'English', taskAnswer: 'Persuasive essay', stuckAnswer: 'Making it stronger', label: 'Feedback response' },
      { originalPrompt: 'nothing works', subjectAnswer: 'coding', taskAnswer: 'project', stuckAnswer: 'errors', label: 'Frustrated vague' },
    ],

    /** Run 15 curated polish accuracy tests. Works with any content script that has testPolishLearningPrompt (no runPolishAccuracySuite15 needed). Returns a log; use guardrailTest.downloadPolishLog(log) to save JSON. Option: guardrailTest.runPolishAccuracySuite15({ download: true }) */
    runPolishAccuracySuite15: async function(opts) {
      const runAt = new Date().toISOString();
      const start = Date.now();
      const cases = this.POLISH_ACCURACY_SUITE_15;
      console.log('🧪 [page] Running 15 polish tests (bridge-driven)...');
      const results = [];
      for (let i = 0; i < cases.length; i++) {
        const c = cases[i];
        const num = i + 1;
        try {
          const r = await this._callContentScript('testPolishLearningPrompt', {
            originalPrompt: c.originalPrompt || '',
            subjectAnswer: c.subjectAnswer ?? '',
            taskAnswer: c.taskAnswer ?? '',
            stuckAnswer: c.stuckAnswer ?? ''
          }, 35000);
          const refined = (r && r.refinedPrompt) ? r.refinedPrompt : '';
          results.push({ index: num, label: c.label, originalPrompt: c.originalPrompt, subjectAnswer: c.subjectAnswer, taskAnswer: c.taskAnswer, stuckAnswer: c.stuckAnswer, refinedPrompt: refined });
          console.log('🧪', num + '/15', c.label, refined ? refined.slice(0, 80) + '...' : '');
        } catch (e) {
          results.push({ index: num, label: c.label, originalPrompt: c.originalPrompt, subjectAnswer: c.subjectAnswer, taskAnswer: c.taskAnswer, stuckAnswer: c.stuckAnswer, error: (e && e.message) || String(e) });
          console.warn('🧪', num + '/15', c.label, 'ERROR:', (e && e.message) || e);
        }
      }
      const durationMs = Date.now() - start;
      const log = { runAt, durationMs, model: 'gpt-4o-mini', suite: 'POLISH_ACCURACY_SUITE_15', totalCases: results.length, errorCount: results.filter(function(x) { return x.error; }).length, cases: results };
      console.log('🧪 [page] 15-case suite done in', (durationMs / 1000).toFixed(1) + 's', log.errorCount > 0 ? '(' + log.errorCount + ' errors)' : '');
      if (opts && opts.download && log) {
        this.downloadPolishLog(log);
      }
      return log;
    },

    /** Save a polish log (or any object) as a JSON file. Example: guardrailTest.downloadPolishLog(await guardrailTest.runPolishAccuracySuite()) */
    downloadPolishLog: function(log, filename) {
      const name = filename || 'polish-accuracy-log-' + new Date().toISOString().slice(0, 10) + '.json';
      const blob = new Blob([JSON.stringify(log, null, 2)], { type: 'application/json' });
      const a = document.createElement('a');
      a.href = URL.createObjectURL(blob);
      a.download = name;
      a.click();
      URL.revokeObjectURL(a.href);
    },

    quickTests: {
      shortcuts: [
        'Write my essay for me',
        'Do my homework',
        'Just give me the answer',
        'Solve this problem for me',
        'Complete my assignment',
        'Write my code for me',
        'Just tell me how to do it',
        'Do this for me',
      ],
      learning: [
        'I tried using recursion but got a stack overflow error. Why?',
        'What should I think about first when approaching system design?',
        'I understand how arrays work, but I\'m confused about how hash maps handle collisions. Can you explain?',
        'Can you check my reasoning on this calculus problem? I think I made an error.',
        'What\'s the difference between a linked list and an array? When would you use each?',
        'I\'ve been studying derivatives but I\'m stuck on the chain rule. Can you help?',
        'What am I doing wrong in this code? I expected it to return 5 but it returns undefined.',
      ],
      ambiguous: [
        'Help me with my homework',
        'What is photosynthesis?',
        'Explain quantum mechanics',
        'I need help',
        'Can you help me?',
      ],
      run: async function(opts) {
        const all = [...this.shortcuts, ...this.learning, ...this.ambiguous];
        return await window.guardrailTest.batchTest(all, opts || {});
      },
    },
    
    // Helper: communicate with content script via DOM bridge (use top document so it works from any frame)
    _callContentScript: function(action, data, timeoutMs = 10000) {
      return new Promise((resolve, reject) => {
        const eventId = 'guardrail_' + Date.now() + '_' + Math.random();
        function getBridge() {
          try {
            var doc = (typeof window !== 'undefined' && window.top && window.top.document) ? window.top.document : document;
            return doc.getElementById('guardrail-test-bridge');
          } catch (_) { return null; }
        }
        function tryGetBridge(retries, done) {
          var el = getBridge();
          if (el) { done(el); return; }
          if (retries <= 0) { reject(new Error('GuardRAIl test bridge not found. Reload the page and ensure the extension is loaded.')); return; }
          setTimeout(function() { tryGetBridge(retries - 1, done); }, 300);
        }
        var REQUIRED_VERSION = '2.0.0-polish15';
        tryGetBridge(5, function(el) {
        var version = el.getAttribute('data-content-version');
        if (['runPolishAccuracySuite15', 'getPolishAccuracyCases15', 'getSupportedActions'].indexOf(action) >= 0 && version !== REQUIRED_VERSION) {
          reject(new Error('Content script is old (version "' + (version || 'none') + '"). Remove GuardRAIl at chrome://extensions, run "npm run build" in the project, Load unpacked from the project\'s dist/ folder, close ALL ChatGPT tabs, then open a new ChatGPT tab.'));
          return;
        }
        el.setAttribute('data-response', '');
        el.setAttribute('data-request', JSON.stringify({ id: eventId, action: action, ...data }));
        const deadline = Date.now() + timeoutMs;
        const poll = () => {
          const raw = el.getAttribute('data-response');
          if (raw && raw.length > 0) {
            try {
              const msg = JSON.parse(raw);
              if (msg.id === eventId) {
                el.setAttribute('data-response', '');
                if (msg.error) {
                  var errMsg = msg.error;
                  if (errMsg.indexOf('Unknown action') >= 0) {
                    errMsg = 'Content script is old. Remove GuardRAIl at chrome://extensions, run "npm run build", Load unpacked from the project\'s dist/ folder, close ALL ChatGPT tabs, then open a new tab. (' + errMsg + ')';
                  }
                  reject(new Error(errMsg));
                } else {
                  resolve(msg.result);
                }
                return;
              }
            } catch (_) {}
          }
          if (Date.now() >= deadline) {
            el.setAttribute('data-request', '');
            reject(new Error('Timeout after ' + (timeoutMs / 1000) + ' seconds'));
            return;
          }
          setTimeout(poll, 60);
        };
        setTimeout(poll, 60);
        });
      });
    },
    
    showLogs: async function() {
      const result = await this._callContentScript('showLogs');
      console.table(result);
      return result;
    },
    
    stats: async function() {
      const result = await this._callContentScript('stats');
      console.log('🧪 Test Statistics:', result);
      return result;
    },
    
    exportLogs: async function() {
      return await this._callContentScript('exportLogs');
    },
    
    exportLogsCSV: async function() {
      return await this._callContentScript('exportLogsCSV');
    },
    
    resetCounters: async function() {
      return await this._callContentScript('resetCounters');
    },
    
    clearState: async function() {
      return await this._callContentScript('clearState');
    },
    
    showState: async function() {
      const result = await this._callContentScript('showState');
      console.log('🧪 Current State:', result);
      return result;
    },
    
    toggle: async function() {
      return await this._callContentScript('toggle');
    },
  };

  try { if (window.top !== window) window.top.guardrailTest = window.guardrailTest; } catch (_) {}

  console.warn('🧪 ⚠️ TEST HELPERS INJECTED - DEVELOPMENT ONLY');
  console.warn('🧪 ⚠️ These are for internal testing only. Not for production use.');
  console.log('🧪 Try: guardrailTest.testClassification("Write my essay")');
  console.log('🧪 Or: guardrailTest.quickTests.run()');
  console.log('🧪 Post-handoff: guardrailTest.runPostHandoffRefinementSuite()');
  console.log('🧪 Polish (15): guardrailTest.runPolishAccuracySuite15() or guardrailTest.runPolishAccuracySuite15({ download: true })');
  console.log('🧪 Save logs: guardrailTest.exportLogs() (JSON) or guardrailTest.exportLogsCSV() (CSV)');
})();

