import { App, Astal, Gdk } from "astal/gtk3";
import { bind, execAsync, interval, timeout, Variable } from "astal";

type AgendaItem = {
  startDate: string;
  startHour: string;
  endDate: string;
  endHour: string;
  activity: string;
};

function transform(stdout: string): AgendaItem {
  const [startDate, startHour, endDate, endHour, activity] = stdout.split("\t");
  return { startDate, startHour, endDate, endHour, activity };
}

// Helper function to get the day name from a date string
function getDayName(dateString: string): string {
  const date = new Date(dateString);
  const dayNames = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ];
  return dayNames[date.getDay()];
}

// Helper function to format the agenda
function createAgenda(agendaItems: AgendaItem[]): string {
  // Group items by date
  const groupedByDate: { [date: string]: AgendaItem[] } = {};

  agendaItems.forEach((item) => {
    if (!groupedByDate[item.startDate]) {
      groupedByDate[item.startDate] = [];
    }
    groupedByDate[item.startDate].push(item);
  });

  // Format each group with extra space between them
  let result = "";
  for (const date in groupedByDate) {
    const dayName = getDayName(date);
    result += `\n${date} - ${dayName}\n`; // Include the day name
    groupedByDate[date].forEach((item) => {
      result += `\t${item.startHour} - ${item.endHour} | ${item.activity}\n`;
    });
    result += "\n"; // Add extra space between date groups
  }

  return result.trim();
}

async function fetchAgenda() {
  const output = await execAsync(["gcalcli", "agenda", "--tsv"]);
  const items = output.trim().split("\n").map(transform);
  return createAgenda(items);
}

export default function Agenda(gdkmonitor: Gdk.Monitor) {
  const text = Variable("");

  const fetchAgendaData = () => {
    fetchAgenda()
      .then((agenda) => text.set(agenda))
      .catch((err) => {
        text.set(`failed to fetch agenda: ${err.message}`);
        timeout(5000, fetchAgendaData);
      });
  };
  const intervalHandler = interval(
    1000 * 60 * 10 /* 10 minutes */,
    fetchAgendaData,
  );
  return (
    <window
      className="Agenda"
      gdkmonitor={gdkmonitor}
      exclusivity={Astal.Exclusivity.EXCLUSIVE}
      anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP}
      layer={Astal.Layer.BOTTOM}
      application={App}
    >
      <button
        borderWidth={0}
        onClick={() => {
          execAsync(["xdg-open", "https://www.google.com/calendar"]);
        }}
      >
        <box
          onDestroy={() => {
            intervalHandler.cancel();
            text.drop();
          }}
        >
          {bind(text)}
        </box>
      </button>
    </window>
  );
}
