import { ref } from 'vue';

import type { ClipboardMatrix } from '../types';

export function useClipboard() {
  const internal = ref<ClipboardMatrix | null>(null);

  function setMatrix(matrix: ClipboardMatrix) {
    internal.value = matrix;
  }

  function getMatrix() {
    return internal.value;
  }

  function hasContent() {
    return !!internal.value?.rows?.length;
  }

  function matrixToTsv(matrix: ClipboardMatrix): string {
    return matrix.rows.map((row) => row.map(String).join('\t')).join('\n');
  }

  function tsvToMatrix(text: string): unknown[][] {
    return text
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n')
      .filter((line, i, arr) => line.length > 0 || i < arr.length - 1)
      .map((line) => line.split('\t'));
  }

  async function writeSystemClipboard(matrix: ClipboardMatrix) {
    const text = matrixToTsv(matrix);
    try {
      await navigator.clipboard.writeText(text);
    } catch {
      // ignore
    }
  }

  async function readSystemClipboard(): Promise<string | null> {
    try {
      return await navigator.clipboard.readText();
    } catch {
      return null;
    }
  }

  return {
    internal,
    setMatrix,
    getMatrix,
    hasContent,
    matrixToTsv,
    tsvToMatrix,
    writeSystemClipboard,
    readSystemClipboard,
  };
}
