"use client";

import { useState, useEffect, useCallback } from "react";
import type { ToolType, ToolEntry, ToolTypeDefinition, ToolConfigField, AppIcon } from "@/lib/types";

export interface UseToolsMenuReturn {
  types: ToolType[];
  tools: ToolEntry[];
  typeDefinitions: Record<string, ToolTypeDefinition>;
  loading: boolean;
  error: string | null;
  // Types
  addType: (data: { name: string; description?: string; icon?: AppIcon; configFields?: ToolConfigField[] }) => Promise<ToolType>;
  updateType: (id: string, updates: { name?: string; description?: string; icon?: AppIcon }) => Promise<void>;
  deleteType: (id: string, cascade?: boolean) => Promise<{ deleted: boolean; affectedTools?: ToolEntry[] }>;
  updateTypeFields: (typeId: string, fields: ToolConfigField[]) => Promise<void>;
  // Tools
  addTool: (data: { name: string; typeId: string; address?: string; description?: string; icon?: AppIcon; color?: string; config?: Record<string, string>; status?: "online" | "offline" }) => Promise<ToolEntry>;
  updateTool: (id: string, updates: Record<string, unknown>) => Promise<void>;
  deleteTool: (id: string) => Promise<void>;
  // View Orders
  updateViewOrder: (viewKey: string, order: string[]) => Promise<void>;
  // Refresh
  refresh: () => void;
}

export function useToolsMenu(): UseToolsMenuReturn {
  const [types, setTypes] = useState<ToolType[]>([]);
  const [tools, setTools] = useState<ToolEntry[]>([]);
  const [typeDefinitions, setTypeDefinitions] = useState<Record<string, ToolTypeDefinition>>({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [refreshKey, setRefreshKey] = useState(0);

  const refresh = useCallback(() => setRefreshKey((k) => k + 1), []);

  useEffect(() => {
    setLoading(true);
    Promise.all([
      fetch("/api/tools-menu/types?includeFields=true").then(r => r.json()),
      fetch("/api/tools-menu/entries").then(r => r.json()),
    ])
      .then(([typesData, toolsData]) => {
        const typesArr = typesData.types as (ToolType & { configFields?: ToolConfigField[] })[];
        setTypes(typesArr.map(({ configFields, ...t }) => t));
        const defs: Record<string, ToolTypeDefinition> = {};
        for (const t of typesArr) {
          defs[t.id] = { typeId: t.id, configFields: t.configFields || [] };
        }
        setTypeDefinitions(defs);
        setTools(toolsData.tools);
        setError(null);
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false));
  }, [refreshKey]);

  const addTypeFn = useCallback(async (data: { name: string; description?: string; icon?: AppIcon; configFields?: ToolConfigField[] }) => {
    const resp = await fetch("/api/tools-menu/types", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    const result = await resp.json();
    refresh();
    return result.type as ToolType;
  }, [refresh]);

  const updateTypeFn = useCallback(async (id: string, updates: { name?: string; description?: string; icon?: AppIcon }) => {
    const resp = await fetch(`/api/tools-menu/types/${encodeURIComponent(id)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    refresh();
  }, [refresh]);

  const deleteTypeFn = useCallback(async (id: string, cascade?: boolean) => {
    const url = cascade ? `/api/tools-menu/types/${encodeURIComponent(id)}?cascade=true` : `/api/tools-menu/types/${encodeURIComponent(id)}`;
    const resp = await fetch(url, { method: "DELETE" });
    const data = await resp.json();
    if (resp.status === 409) return { deleted: false, affectedTools: data.affectedTools as ToolEntry[] };
    if (!resp.ok) throw new Error(data.error);
    refresh();
    return { deleted: true };
  }, [refresh]);

  const updateTypeFieldsFn = useCallback(async (typeId: string, fields: ToolConfigField[]) => {
    const resp = await fetch(`/api/tools-menu/types/${encodeURIComponent(typeId)}/fields`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ fields }),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    refresh();
  }, [refresh]);

  const addToolFn = useCallback(async (data: { name: string; typeId: string; address?: string; description?: string; icon?: AppIcon; color?: string; config?: Record<string, string>; status?: "online" | "offline" }) => {
    const resp = await fetch("/api/tools-menu/entries", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    const result = await resp.json();
    refresh();
    return result.tool as ToolEntry;
  }, [refresh]);

  const updateToolFn = useCallback(async (id: string, updates: Record<string, unknown>) => {
    const resp = await fetch(`/api/tools-menu/entries/${encodeURIComponent(id)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    refresh();
  }, [refresh]);

  const deleteToolFn = useCallback(async (id: string) => {
    const resp = await fetch(`/api/tools-menu/entries/${encodeURIComponent(id)}`, { method: "DELETE" });
    if (!resp.ok) throw new Error((await resp.json()).error);
    refresh();
  }, [refresh]);

  const updateViewOrderFn = useCallback(async (viewKey: string, order: string[]) => {
    const resp = await fetch(`/api/tools-menu/view-orders/${encodeURIComponent(viewKey)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ order }),
    });
    if (!resp.ok) throw new Error((await resp.json()).error);
    refresh();
  }, [refresh]);

  return {
    types, tools, typeDefinitions, loading, error,
    addType: addTypeFn, updateType: updateTypeFn, deleteType: deleteTypeFn, updateTypeFields: updateTypeFieldsFn,
    addTool: addToolFn, updateTool: updateToolFn, deleteTool: deleteToolFn,
    updateViewOrder: updateViewOrderFn,
    refresh,
  };
}
