// SyncStore - Handles data synchronization between local storage and server
import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { useAuthStore } from "./auth";

interface PendingItem {
  id: string;
  type: "transaction" | "category";
  action: "create" | "update" | "delete";
  data: any;
  timestamp: number;
}

export const useSyncStore = defineStore("sync", () => {
  // State
  const pendingActions = ref<PendingItem[]>([]);
  const isSyncing = ref(false);
  const lastSyncTime = ref<number>(
    parseInt(localStorage.getItem("lastSyncTime") || "0"),
  );
  const syncErrors = ref<string[]>([]);
  const isOnline = ref(navigator.onLine);

  // API URL
  const apiBaseUrl = "http://localhost:3000/api";

  // Auth store for token
  const authStore = useAuthStore();

  // Initialize online/offline listeners
  window.addEventListener("online", () => {
    isOnline.value = true;
    if (pendingActions.value.length > 0) {
      syncWithServer();
    }
  });

  window.addEventListener("offline", () => {
    isOnline.value = false;
  });

  // Load pending actions from localStorage
  function loadFromLocalStorage() {
    const savedActions = localStorage.getItem("pendingActions");
    if (savedActions) {
      pendingActions.value = JSON.parse(savedActions);
    }
  }

  // Save pending actions to localStorage
  function saveToLocalStorage() {
    localStorage.setItem(
      "pendingActions",
      JSON.stringify(pendingActions.value),
    );
  }

  // Add pending action
  function addPendingAction(
    type: "transaction" | "category",
    action: "create" | "update" | "delete",
    data: any,
  ) {
    const id = `${type}_${Date.now()}`;
    pendingActions.value.push({
      id,
      type,
      action,
      data,
      timestamp: Date.now(),
    });
    saveToLocalStorage();

    if (isOnline.value && authStore.isAuthenticated) {
      syncWithServer();
    } else if ("serviceWorker" in navigator && "SyncManager" in window) {
      // Register for background sync
      navigator.serviceWorker.ready
        .then((registration) => {
          registration.sync.register(`sync-${type}s`);
        })
        .catch((err) => {
          console.error("Background sync registration failed:", err);
        });
    }

    return id;
  }

  // Remove pending action
  function removePendingAction(id: string) {
    const index = pendingActions.value.findIndex((item) => item.id === id);
    if (index !== -1) {
      pendingActions.value.splice(index, 1);
      saveToLocalStorage();
    }
  }

  // Sync with server
  async function syncWithServer() {
    if (
      isSyncing.value ||
      !authStore.token ||
      pendingActions.value.length === 0
    ) {
      return;
    }

    isSyncing.value = true;
    syncErrors.value = [];

    try {
      // Clone the array to avoid mutation issues during iteration
      const actions = [...pendingActions.value];

      for (const action of actions) {
        try {
          if (action.type === "transaction") {
            await syncTransaction(action);
          } else if (action.type === "category") {
            await syncCategory(action);
          }
        } catch (err: any) {
          syncErrors.value.push(
            `Failed to sync ${action.type}: ${err.message}`,
          );
        }
      }

      // Update last sync time
      lastSyncTime.value = Date.now();
      localStorage.setItem("lastSyncTime", lastSyncTime.value.toString());
    } catch (err: any) {
      syncErrors.value.push(`Sync error: ${err.message}`);
    } finally {
      isSyncing.value = false;
    }
  }

  // Sync a transaction
  async function syncTransaction(item: PendingItem) {
    let method = "POST";
    let url = `${apiBaseUrl}/transactions`;

    if (item.action === "update") {
      method = "PUT";
      url = `${apiBaseUrl}/transactions/${item.data._id}`;
    } else if (item.action === "delete") {
      method = "DELETE";
      url = `${apiBaseUrl}/transactions/${item.data._id}`;
    }

    const response = await fetch(url, {
      method,
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${authStore.token}`,
      },
      body: method !== "DELETE" ? JSON.stringify(item.data) : undefined,
    });

    if (response.ok) {
      removePendingAction(item.id);
    } else {
      throw new Error(`Server returned ${response.status}`);
    }
  }

  // Sync a category
  async function syncCategory(item: PendingItem) {
    let method = "POST";
    let url = `${apiBaseUrl}/categories`;

    if (item.action === "update") {
      method = "PUT";
      url = `${apiBaseUrl}/categories/${item.data._id}`;
    } else if (item.action === "delete") {
      method = "DELETE";
      url = `${apiBaseUrl}/categories/${item.data._id}`;
    }

    const response = await fetch(url, {
      method,
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${authStore.token}`,
      },
      body: method !== "DELETE" ? JSON.stringify(item.data) : undefined,
    });

    if (response.ok) {
      removePendingAction(item.id);
    } else {
      throw new Error(`Server returned ${response.status}`);
    }
  }

  // Initialize
  loadFromLocalStorage();

  return {
    // State
    pendingActions,
    isSyncing,
    lastSyncTime,
    syncErrors,
    isOnline,

    // Actions
    addPendingAction,
    removePendingAction,
    syncWithServer,
  };
});
