const patterns = {
  poems: /\bpoems?\b/,
  thanks: /\bthank(s| you)?\b/,
  hello: /\b(hi|hel?lo|hey|howdy|what((’|')s)? ?up)\b/,
  help: /\b(help(me)?|how do)\b/,
  wow: /\bwow\b/,
};

let poem_list = [];
const poem_list_loaded = fetch('./js/poem-list.json')
.then(response => response.json())
.then(list => poem_list = list);

let poem_patterns = [];
fetch('./js/pattern-overrides.json')
.then(response => response.json())
.then(async list => {
  poem_patterns = (await poem_list_loaded).map(
    ({filename}) => {
      const result = list.find(([name]) => name === filename);
      return [filename, new RegExp(`\\b${result ? result[1] : filename}\\b`)];
    }
  )
});

let fail_count = 0;

async function gpt(message) {
  const response = await chat(message);
  if (!response) {
    fail_count += 1;
    if (fail_count >= 3) {
      return 'Try typing “help”';
    }
    return `You said: “${message}”`;
  } else {
    fail_count = 0;
    return response;
  }
}

function chat(message) {
  message = message.toLowerCase();
  if (patterns.poems.test(message)) {
    return { poem_list };
  } else if (patterns.thanks.test(message)) {
    return ['You’re welcome 😅', 'Sure thing!'].sample();
  } else if (patterns.hello.test(message)) {
    return ['Howdy! I can show you some poems.', 'Greetings! I can show you poems.'].sample();
  } else if (patterns.help.test(message)) {
    return 'Type “poems” to see a list of poems I can show you.';
  } else if (patterns.wow.test(message)) {
    return 'Yeah, wow! 🤯';
  } else {
    for (const [name, pattern] of poem_patterns) {
      if (pattern.test(message)) {
        return poem(name);
      }
    }
  }
}

async function poem(filename) {
  return fetch('./poems/' + filename)
    .then(response => {
      if (response.ok) {
        return response.text();
      } else {
        throw null;
      }
    })
    .then(file => file
      .replaceAll('\r\n', '\n')
      .replaceAll('\t', TAB)
      .split('\n')
    )
    .then(lines => {
      const title = lines[0];
      const author = lines[1];

      const poem = {
        title,
        author,
        lines: lines.slice(2)
      };

      return { poem };
    })
    .catch(() => ({ error: 'Failed to get poem.' }));
}

const TAB = '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0';

Array.prototype.sample = function(){
  return this[~~(Math.random() * this.length)];
}

export default gpt;
