"use client";

import { useState, useEffect, useCallback } from "react";
import type { SkillDefinition } from "@/lib/types";

interface SkillWithContent extends SkillDefinition {
  content?: string;
}

interface UseSkillsReturn {
  skills: SkillDefinition[];
  loading: boolean;
  error: string | null;
  selectedSkill: SkillWithContent | null;
  selectSkill: (name: string) => void;
  clearSelection: () => void;
  addSkillFromPath: (path: string) => Promise<void>;
  addSkillFromFile: (file: File) => Promise<void>;
  updateSkill: (name: string, updates: { description?: string; version?: string; allowedTools?: string[]; content?: string }) => Promise<void>;
  deleteSkill: (name: string, deleteFile?: boolean) => Promise<void>;
  updateAgents: (name: string, agents: string[]) => Promise<void>;
  refresh: () => void;
}

export function useSkills(): UseSkillsReturn {
  const [skills, setSkills] = useState<SkillDefinition[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedSkill, setSelectedSkill] = useState<SkillWithContent | null>(null);
  const [refreshKey, setRefreshKey] = useState(0);

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

  useEffect(() => {
    setLoading(true);
    fetch("/api/skills")
      .then((r) => r.json())
      .then((data: { skills: SkillDefinition[] }) => {
        setSkills(data.skills);
        setError(null);
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false));
  }, [refreshKey]);

  const selectSkill = useCallback((name: string) => {
    fetch(`/api/skills/${encodeURIComponent(name)}`)
      .then((r) => r.json())
      .then((data: { skill: SkillWithContent }) => setSelectedSkill(data.skill))
      .catch((err) => setError(err.message));
  }, []);

  const clearSelection = useCallback(() => setSelectedSkill(null), []);

  const addSkillFromPath = useCallback(async (path: string) => {
    const resp = await fetch("/api/skills", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ path }),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to add skill");
    }
    refresh();
  }, [refresh]);

  const addSkillFromFile = useCallback(async (file: File) => {
    const formData = new FormData();
    formData.append("file", file);
    const resp = await fetch("/api/skills", { method: "POST", body: formData });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to add skill");
    }
    refresh();
  }, [refresh]);

  const updateSkillFn = useCallback(async (name: string, updates: { description?: string; version?: string; allowedTools?: string[]; content?: string }) => {
    const resp = await fetch(`/api/skills/${encodeURIComponent(name)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to update skill");
    }
    const data = await resp.json();
    setSelectedSkill((prev) => prev ? { ...prev, ...data.skill } : null);
    refresh();
  }, [refresh]);

  const deleteSkillFn = useCallback(async (name: string, deleteFile = false) => {
    const resp = await fetch(
      `/api/skills/${encodeURIComponent(name)}?deleteFile=${deleteFile}`,
      { method: "DELETE" }
    );
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to delete skill");
    }
    setSelectedSkill(null);
    refresh();
  }, [refresh]);

  const updateAgents = useCallback(async (name: string, agents: string[]) => {
    const resp = await fetch(`/api/skills/${encodeURIComponent(name)}/agents`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ agents }),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to update agents");
    }
    const data = await resp.json();
    setSelectedSkill((prev) => prev ? { ...prev, agents: data.skill.agents } : null);
    refresh();
  }, [refresh]);

  return {
    skills,
    loading,
    error,
    selectedSkill,
    selectSkill,
    clearSelection,
    addSkillFromPath,
    addSkillFromFile,
    updateSkill: updateSkillFn,
    deleteSkill: deleteSkillFn,
    updateAgents,
    refresh,
  };
}
