import { useState, useEffect, useCallback, useRef } from "react";
import type {
  BackupSettings,
  BackupHealth,
  BackupStatus,
  BackupHistoryEntry,
  BackupDestination,
  BackupRunRequest,
} from "@/lib/types";

export function useBackupService() {
  const [health, setHealth] = useState<BackupHealth | null>(null);
  const [settings, setSettings] = useState<BackupSettings | null>(null);
  const [status, setStatus] = useState<BackupStatus | null>(null);
  const [history, setHistory] = useState<BackupHistoryEntry[]>([]);
  const [destinations, setDestinations] = useState<BackupDestination[]>([]);
  const [volumes, setVolumes] = useState<{ name: string; path: string; type: string }[]>([]);
  const [loading, setLoading] = useState(true);

  const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const fetchAll = useCallback(async () => {
    try {
      const [healthRes, settingsRes, statusRes, historyRes, destsRes, volsRes] = await Promise.all([
        fetch("/api/admin/backup/health"),
        fetch("/api/admin/backup/settings"),
        fetch("/api/admin/backup/status"),
        fetch("/api/admin/backup/history"),
        fetch("/api/admin/backup/destinations"),
        fetch("/api/admin/backup/volumes"),
      ]);
      if (healthRes.ok) setHealth(await healthRes.json());
      if (settingsRes.ok) setSettings(await settingsRes.json());
      if (statusRes.ok) setStatus(await statusRes.json());
      if (historyRes.ok) setHistory(await historyRes.json());
      if (destsRes.ok) setDestinations(await destsRes.json());
      if (volsRes.ok) setVolumes(await volsRes.json());
    } catch {
      // Service offline
    } finally {
      setLoading(false);
    }
  }, []);

  const pollStatus = useCallback(async () => {
    try {
      const res = await fetch("/api/admin/backup/status");
      if (res.ok) {
        const data: BackupStatus = await res.json();
        setStatus(data);

        if (data.state === "idle" && pollingRef.current) {
          clearInterval(pollingRef.current);
          pollingRef.current = null;
          fetchAll();
        }
      }
    } catch {
      // ignore
    }
  }, [fetchAll]);

  useEffect(() => {
    fetchAll();
  }, [fetchAll]);

  useEffect(() => {
    if (status?.state === "running" && !pollingRef.current) {
      pollingRef.current = setInterval(pollStatus, 2000);
    }
    return () => {
      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
    };
  }, [status?.state, pollStatus]);

  const updateSettings = useCallback(async (updates: Partial<BackupSettings>) => {
    const res = await fetch("/api/admin/backup/settings", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (res.ok) {
      const data = await res.json();
      setSettings(data);
    }
  }, []);

  const runBackup = useCallback(async (request: BackupRunRequest) => {
    const res = await fetch("/api/admin/backup/run", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(request),
    });
    if (res.ok) {
      setStatus({ state: "running", backupType: request.backupType, destinationId: request.destinationId });
    }
    return res.ok;
  }, []);

  const addDestination = useCallback(async (dest: Omit<BackupDestination, "id">) => {
    const res = await fetch("/api/admin/backup/destinations", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(dest),
    });
    if (res.ok) {
      const newDest = await res.json();
      setDestinations((prev) => [...prev, newDest]);
      return newDest;
    }
  }, []);

  const updateDestination = useCallback(async (id: string, updates: Partial<BackupDestination>) => {
    const res = await fetch(`/api/admin/backup/destinations/${encodeURIComponent(id)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (res.ok) {
      const updated = await res.json();
      setDestinations((prev) => prev.map((d) => (d.id === id ? updated : d)));
    }
  }, []);

  const removeDestination = useCallback(async (id: string) => {
    const res = await fetch(`/api/admin/backup/destinations/${encodeURIComponent(id)}`, {
      method: "DELETE",
    });
    if (res.ok) {
      setDestinations((prev) => prev.filter((d) => d.id !== id));
    }
  }, []);

  const testDestination = useCallback(async (id: string) => {
    const res = await fetch(`/api/admin/backup/destinations/${encodeURIComponent(id)}/test`, {
      method: "POST",
    });
    if (res.ok) {
      return await res.json();
    }
    return { success: false, message: "Service unavailable" };
  }, []);

  return {
    health,
    settings,
    status,
    history,
    destinations,
    volumes,
    loading,
    updateSettings,
    runBackup,
    addDestination,
    updateDestination,
    removeDestination,
    testDestination,
    refresh: fetchAll,
  };
}
