"use client";

import { useState, useEffect, useCallback } from "react";
import { v4 as uuid } from "uuid";
import type { VaultEntry, VaultEntryCategory } from "../types";

export interface VaultFilters {
  search: string;
  category: VaultEntryCategory | "all";
}

/**
 * Vault hook — uses dedicated /api/vault endpoint with server-side encryption.
 * Passwords are encrypted at rest (AES-256-GCM) and decrypted only on read.
 */
export function useVault() {
  const [entries, setEntries] = useState<VaultEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [filters, setFilters] = useState<VaultFilters>({
    search: "",
    category: "all",
  });

  const refresh = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/vault");
      const data = await res.json();
      const results = ((data.entries ?? []) as VaultEntry[]).map((e) => ({
        ...e,
        additionalUsers: e.additionalUsers ?? [],
        customFields: e.customFields ?? [],
      }));
      results.sort((a, b) => a.label.localeCompare(b.label));
      setEntries(results);
    } catch (err) {
      console.error("Failed to load vault entries:", err);
    } finally {
      setLoading(false);
    }
  }, []);

  // eslint-disable-next-line react-hooks/set-state-in-effect
  useEffect(() => {
    refresh();
  }, [refresh]);

  const addEntry = useCallback(
    async (data: Omit<VaultEntry, "id" | "createdAt" | "updatedAt">) => {
      const now = new Date().toISOString();
      const entry: VaultEntry = {
        ...data,
        id: uuid(),
        createdAt: now,
        updatedAt: now,
      };
      await fetch("/api/vault", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ entry }),
      });
      await refresh();
      return entry;
    },
    [refresh],
  );

  const updateEntry = useCallback(
    async (id: string, updates: Partial<VaultEntry>) => {
      const existing = entries.find((e) => e.id === id);
      if (!existing) return;
      const updated: VaultEntry = {
        ...existing,
        ...updates,
        id: existing.id,
        createdAt: existing.createdAt,
        updatedAt: new Date().toISOString(),
      };
      await fetch("/api/vault", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ entry: updated }),
      });
      await refresh();
    },
    [refresh, entries],
  );

  const removeEntry = useCallback(
    async (id: string) => {
      await fetch(`/api/vault?id=${encodeURIComponent(id)}`, {
        method: "DELETE",
      });
      await refresh();
    },
    [refresh],
  );

  const updateFilter = useCallback(
    <K extends keyof VaultFilters>(key: K, value: VaultFilters[K]) => {
      setFilters((prev) => ({ ...prev, [key]: value }));
    },
    [],
  );

  const filteredEntries = entries.filter((e) => {
    if (filters.category !== "all" && e.category !== filters.category)
      return false;
    if (filters.search) {
      const q = filters.search.toLowerCase();
      return (
        e.label.toLowerCase().includes(q) ||
        e.username.toLowerCase().includes(q) ||
        e.url.toLowerCase().includes(q)
      );
    }
    return true;
  });

  return {
    entries: filteredEntries,
    allEntries: entries,
    loading,
    filters,
    updateFilter,
    addEntry,
    updateEntry,
    removeEntry,
    refresh,
  };
}
