import { PrismaClient } from "@prisma/client";
import LCD from "raspberrypi-liquid-crystal";
import fs from "node:fs";
import * as WavFileDecoder from "wav-file-decoder";

const timer = (ms: number) => new Promise((res) => setTimeout(res, ms));

const prisma = new PrismaClient();
const getStanza = async (register: string) => {
  const stanzaCount = await prisma.stanza.count({ where: { register } });
  const skip = Math.floor(Math.random() * stanzaCount);

  const randomStanza = await prisma.stanza.findMany({
    skip: skip,
    take: 1,
    where: {
      register,
    },
  });

  return randomStanza[0].text as string;
};

// Play portal wave PCM data and set bands
const fileData = fs.readFileSync("/home/grace/portal/blackportal1000.wav");
const wavFileInfo = WavFileDecoder.getWavFileInfo(fileData);
const audioData = WavFileDecoder.decodeWavFile(fileData);
const totalSamples = wavFileInfo.chunkInfo.filter(
  (ci) => ci.chunkId === "data"
)[0].dataLength;

let sample = 0;
let register = "high";
let count = 0;

setInterval(() => {
  const absSample = Math.abs(audioData.channelData[0][count]);
  if (count == totalSamples - 1) {
    count = 0;
  } else {
    count++;
  }
  register = "high";
  if (absSample < 0.01) {
    register = "mid";
  }
  if (absSample < 0.001) {
    register = "low";
  }

  sample = absSample;
}, 1);

const lcd = new LCD(1, 0x27, 16, 2);
lcd.beginSync();
lcd.clearSync();

const TICK = 250;
const WAIT = 10;

// Play bottom line
const tag =
  "                Black Portal 4856 E Davison, Detroit                                                                ";
let tagCharacterLocation = 0;

setInterval(() => {
  lcd.printLineSync(1, "                ");
  setTimeout(() => {
    lcd.printLineSync(
      1,
      tag.substring(tagCharacterLocation, 16 + tagCharacterLocation)
    );
  }, WAIT);

  tagCharacterLocation++;
  if (tagCharacterLocation > tag.length) {
    tagCharacterLocation = 0;
  }
}, TICK);

// Play top line
let stanzaCharacterLocation = 0;
let stanza = await getStanza(register);
while (true) {
  if (stanzaCharacterLocation == stanza.length) {
    stanzaCharacterLocation = 0;
    stanza = await getStanza(register);
  }

  lcd.printLineSync(0, "                ");
  setTimeout(() => {
    lcd.printLineSync(
      0,
      `${
        16 - stanzaCharacterLocation > 0
          ? Array(16 - stanzaCharacterLocation).join(" ")
          : ""
      }${stanza}`.substring(stanzaCharacterLocation, stanza.length)
    );
  }, WAIT);
  await timer(TICK);
  stanzaCharacterLocation++;
}
