import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { TableMeta } from "@/viewmodels/admin/configuration/query.models";
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";

export const useQueryBuilderStore = defineStore("queryBuilder", {
  state: () => {
    return {
      tableMetas: [] as Array<TableMeta>,
      loading: "loading" as "loading" | "fetched" | "failed",
      data: [] as Array<{ id: FieldType; [key: string]: FieldType }>,
      totalLength: 0 as number,
      loadingData: "fetched" as "loading" | "fetched" | "failed",
      queryError: "" as string | { sql: string; code: string; msg: string },
      query: undefined as undefined | DynamicQueryStructure | string,
      activeQueryId: undefined as undefined | string,
    };
  },
  actions: {
    fetchTableMetas() {
      this.loading = "loading";
      http
        .get("/admin/querybuilder/tables")
        .then((result) => {
          this.tableMetas = result.data;
          this.loading = "fetched";
        })
        .catch((err) => {
          this.loading = "failed";
        });
    },
    async sendQuery(offset = 0, count = 25, query?: DynamicQueryStructure | string, noLimit: boolean = false) {
      this.queryError = "";
      if (offset == 0) {
        this.data = [];
        this.totalLength = 0;
      }
      let queryToSend = query ?? this.query;
      if (queryToSend == undefined || queryToSend == "" || (typeof queryToSend != "string" && queryToSend.table == ""))
        return;
      this.loadingData = "loading";
      await http
        .post(`/admin/querybuilder/query?` + (noLimit ? `noLimit=true` : `offset=${offset}&count=${count}`), {
          query: queryToSend,
        })
        .then((result) => {
          if (result.data.stats == "success") {
            this.data = [...this.data, ...result.data.rows];
            this.totalLength = result.data.total;
            this.loadingData = "fetched";
          } else {
            this.queryError = result.data ?? "An error occurred";
            this.loadingData = "failed";
          }
        })
        .catch((err) => {
          this.queryError = "An error occurred";
          this.loadingData = "failed";
        });
    },
    clearResults() {
      this.data = [];
      this.totalLength = 0;
      this.queryError = "";
      this.loadingData = "fetched";
    },
    async exportData() {
      await this.sendQuery(0, 0, undefined, true);
      if (this.data.length == 0) return;
      const csvString = [Object.keys(this.data[0]), ...this.data.map((d) => Object.values(d))]
        .map((e) => e.join(";"))
        .join("\n");

      // Create a Blob from the CSV string
      const blob = new Blob([csvString], { type: "text/csv" });

      // Create a download link
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "items.csv";

      // Append the link to the document and trigger the download
      document.body.appendChild(a);
      a.click();

      // Clean up
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    },
  },
});