import type { Ref } from 'vue';
import { ref } from 'vue';
import type { IntervalTemplate } from '~/utils/schedule.types';
import { defineStore } from 'pinia';
import { AppwriteIds, databases } from '~/utils/appwrite';
import type { Models } from 'appwrite';
import { ID } from 'appwrite';
import { arrayToTimeTuples } from '~/utils/schedule';

export const useIntervalTemplateStore = defineStore('intervalTemplate', () => {
  const intervalTemplates = ref<IntervalTemplate[]>([]);

  const getIntervalTemplates = (): Ref<IntervalTemplate[]> => {
    if (!intervalTemplates.value) fetchIntervalTemplates();
    return intervalTemplates;
  };

  async function fetchIntervalTemplates() {
    try {
      const response = await databases.listDocuments(
        AppwriteIds.databaseId,
        AppwriteIds.collection.intervalTemplate
      );
      intervalTemplates.value = response.documents.map((d): IntervalTemplate => {
        const doc = d as unknown as { timeTuple: string[] } & Models.Document;
        return {
          ...doc,
          timeTuples: arrayToTimeTuples(doc.timeTuple),
        } as unknown as IntervalTemplate;
      });
    } catch (error) {
      console.error('Failed to fetch timeblock templates', error);
    }
  }

  const createIntervalTemplate = async (template: IntervalTemplate) => {
    try {
      const response = await databases.createDocument(
        AppwriteIds.databaseId,
        AppwriteIds.collection.intervalTemplate,
        ID.unique(),
        { name: template.name, timeTuple: template.timeTuples.flat(2) }
      );
      intervalTemplates.value.push(response as unknown as IntervalTemplate);
    } catch (e) {
      console.error('Error creating IntervalTemplate: ' + e);
    }
  };

  const deleteIntervalTemplate = async (id: string) => {
    try {
      await databases.deleteDocument(
        AppwriteIds.databaseId,
        AppwriteIds.collection.intervalTemplate,
        id
      );
      intervalTemplates.value = intervalTemplates.value.filter(
        (template) => template.$id !== id
      );
    } catch (e) {
      console.error('Error deleting IntervalTemplate: ' + e);
    }
  };

  const updateIntervalTemplate = async (
    template: IntervalTemplate,
    id: string
  ) => {
    try {
      const response = await databases.updateDocument(
        AppwriteIds.databaseId,
        AppwriteIds.collection.intervalTemplate,
        id,
        {
          name: template.name,
          timeTuple: template.timeTuples.flat(2),
        }
      );
      intervalTemplates.value = intervalTemplates.value.map((b) =>
        b.$id !== id
          ? b
          : ({
              ...response,
              timeTuples: arrayToTimeTuples(
                (response as unknown as { timeTuple: string[] }).timeTuple
              ),
            } as unknown as IntervalTemplate)
      );
    } catch (e) {
      console.error('Error updating IntervalTemplate: ' + e);
    }
  };

  return {
    getIntervalTemplates,
    fetchIntervalTemplates,
    createIntervalTemplate,
    deleteIntervalTemplate,
    updateIntervalTemplate,
  };
});
