import {Operator, getUrlParameter} from './utils';
import {LitElement, html, css, render} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {StorageUtil} from './storage';

function nextTick(ts: number) {
  return new Promise(resolve => {
    setTimeout(resolve, ts);
  });
}

// Since content-script can not access window.Gerrit,
// here checks the readiness based on #mainHeader element
// Wait at most 5s before considering it as loaded.
const MAX_WAIT_TIME = 5000;
const getHeaderEl = () => {
  if (document.querySelector('#app')) {
    return document
      .querySelector('#app')
      .shadowRoot.querySelector('#app-element')
      .shadowRoot.querySelector('#mainHeader');
  } else {
    return document
      .querySelector('gr-app')
      .shadowRoot.querySelector('gr-app-element')
      .shadowRoot.querySelector('gr-main-header');
  }
};

const onGerritReady = async () => {
  let header;
  try {
    header = getHeaderEl();
  } catch (e) {}

  let waitTime = 0;
  while (!header) {
    if (waitTime > MAX_WAIT_TIME) break;
    waitTime += 1000;
    await nextTick(1000);
    try {
      header = getHeaderEl();
    } catch (e) {}
  }
  return true;
};

let numOfSnackBars = 0;

@customElement('gdh-snackbar')
export class HelperSnackbar extends LitElement {
  @property({type: String}) message = '';

  @property({type: Number}) position = 0;

  render() {
    this.style.top = `${this.position * 40}px`;
    return html`<div>${this.message}</div>`;
  }

  static get styles() {
    return css`
      :host {
        position: absolute;
        top: 0px;
        right: 0px;
        background-color: black;
        color: white;
        padding: 10px;
        z-index: 100;
      }
    `;
  }
}

@customElement('gdh-tip')
export class HelperTip extends LitElement {
  @state() numErrors = 0;

  constructor() {
    super();
    this.interceptErrors();
  }

  interceptErrors() {
    let original = console.error;
    console.error = (...args) => {
      original.call(console, ...args);
      this.numErrors++;
    };
  }

  render() {
    const errors = this.numErrors > 0 ? ` (${this.numErrors} js errors)` : '';
    return html`<div>Gerrit dev helper is enabled ${errors}</div>`;
  }

  static get styles() {
    return css`
      :host {
        z-index: 10000;
        display: block;
        position: fixed;
        bottom: 0;
        right: 0;
        background-color: red;
      }
      div {
        color: white;
        font-weight: bold;
        padding: 10px;
      }
    `;
  }
}

// Apply injection rules to Gerrit sites if enabled
chrome.runtime.sendMessage({type: 'isEnabled'}, async isEnabled => {
  if (!isEnabled) return;

  console.log('Gerrit FE Dev Helper is enabled.');
  render(html`<gdh-tip></gdh-tip>`, document.body);

  const storage = new StorageUtil();
  const rules = await storage.getRules();

  for (const rule of rules) {
    if (rule.disabled) continue;
    if (rule.operator === Operator.INJECT_HTML_CODE) {
      const el = document.createElement('div');
      el.innerHTML = rule.destination;
      document.body.appendChild(el);
    } else if (rule.operator === Operator.INJECT_CSS) {
      onGerritReady().then(() => {
        const link = document.createElement('link');
        link.setAttribute('rel', 'stylesheet');
        link.setAttribute('href', rule.destination);
        document.head.appendChild(link);
      });
    } else if (rule.operator === Operator.INJECT_JS_PLUGIN) {
      onGerritReady().then(() => {
        const link = document.createElement('script');
        link.setAttribute('src', rule.destination);
        link.setAttribute('crossorigin', 'anonymous');
        document.head.appendChild(link);
      });
    } else if (rule.operator === Operator.INJECT_JS_MODULE_PLUGIN) {
      onGerritReady().then(() => {
        const link = document.createElement('script');
        link.setAttribute('type', 'module');
        link.setAttribute('src', rule.destination);
        link.setAttribute('crossorigin', 'anonymous');
        document.head.appendChild(link);
      });
    } else if (rule.operator === Operator.INJECT_EXP) {
      const exps = getUrlParameter('experiment');
      const hasSearchString = !!window.location.search;
      const injectedExpNotInExps = new Set(
        rule.destination
          .trim()
          .split(',')
          .filter(exp => !exps.includes(exp.trim()))
      );
      if (injectedExpNotInExps.size) {
        const addedParams = [...injectedExpNotInExps].reduce(
          (str, exp) => (str += `experiment=${exp}&`),
          ''
        );
        window.location.href += hasSearchString
          ? `&${addedParams}`
          : `?${addedParams}`;
      }
    }
  }

  // Test redirect rules. Show a warning, if they are obviously not working as intended.
  for (const rule of rules) {
    if (
      rule.operator === Operator.REDIRECT &&
      !rule.disabled &&
      // only test for js/html
      /\.(js|html)+$/.test(rule.destination)
    ) {
      fetch(rule.destination)
        .then(res => {
          if (res.status < 200 || res.status >= 300)
            throw new Error('Resource not found');
        })
        .catch(e => {
          const message = `You may have an invalid redirect rule from ${rule.target} to ${rule.destination}`;
          const id = `snack-${numOfSnackBars}`;
          render(
            html`
              <gdh-snackbar
                id=${id}
                .message=${message}
                .position=${numOfSnackBars}
              ></gdh-snackbar>
            `,
            document.body
          );
          numOfSnackBars++;

          // in case body is unresolved
          document.body.style.display = 'block';
          document.body.style.opacity = '1';

          setTimeout(() => {
            document.getElementById(id)?.remove();
            numOfSnackBars--;
          }, 10 * 1000);
        });
    }
  }
});
