"use client";

import { useState, useEffect, useCallback } from "react";
import { useStorage } from "@/core/storage";
import { v4 as uuid } from "uuid";
import type { WordTemplate, TemplateCategory } from "../types";

const PREFIX = "tpl:";

export interface TemplateFilters {
  search: string;
  category: TemplateCategory | "all";
  company: string;
}

/** Increment a semver-like version string (e.g. "1.2" → "1.3") */
function bumpVersion(ver: string): string {
  const parts = ver.split(".");
  if (parts.length >= 2) {
    const minor = parseInt(parts[parts.length - 1] ?? "0", 10);
    parts[parts.length - 1] = String(isNaN(minor) ? 1 : minor + 1);
    return parts.join(".");
  }
  return `${ver}.1`;
}

export function useTemplates() {
  const storage = useStorage("word-templates");
  const [templates, setTemplates] = useState<WordTemplate[]>([]);
  const [loading, setLoading] = useState(true);
  const [filters, setFilters] = useState<TemplateFilters>({
    search: "",
    category: "all",
    company: "all",
  });

  const refresh = useCallback(async () => {
    setLoading(true);
    const all = await storage.exportAll();
    const results: WordTemplate[] = [];
    for (const [key, value] of Object.entries(all)) {
      if (key.startsWith(PREFIX) && value) {
        const tpl = value as WordTemplate;
        // Backfill new fields for old entries
        if (!tpl.fileType) tpl.fileType = "docx";
        if (!tpl.versionHistory) tpl.versionHistory = [];
        results.push(tpl);
      }
    }
    results.sort((a, b) => a.name.localeCompare(b.name));
    setTemplates(results);
    setLoading(false);
  }, [storage]);

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

  const addTemplate = useCallback(
    async (data: Omit<WordTemplate, "id" | "createdAt" | "updatedAt">) => {
      const now = new Date().toISOString();
      const template: WordTemplate = {
        ...data,
        id: uuid(),
        createdAt: now,
        updatedAt: now,
      };
      await storage.set(`${PREFIX}${template.id}`, template);
      await refresh();
      return template;
    },
    [storage, refresh],
  );

  const updateTemplate = useCallback(
    async (id: string, updates: Partial<WordTemplate>) => {
      const existing = templates.find((t) => t.id === id);
      if (!existing) return;
      const updated: WordTemplate = {
        ...existing,
        ...updates,
        id: existing.id,
        createdAt: existing.createdAt,
        updatedAt: new Date().toISOString(),
      };
      await storage.set(`${PREFIX}${id}`, updated);
      await refresh();
    },
    [storage, refresh, templates],
  );

  /** Create a new revision: archives current version in history, bumps version */
  const createRevision = useCallback(
    async (id: string, newFileUrl: string, notes: string) => {
      const existing = templates.find((t) => t.id === id);
      if (!existing) return;
      const now = new Date().toISOString();
      const history = [...(existing.versionHistory ?? [])];
      // Archive current version
      history.push({
        version: existing.version,
        fileUrl: existing.fileUrl,
        notes: "",
        createdAt: existing.updatedAt,
      });
      const updated: WordTemplate = {
        ...existing,
        version: bumpVersion(existing.version),
        fileUrl: newFileUrl || existing.fileUrl,
        versionHistory: history,
        updatedAt: now,
      };
      if (notes) {
        updated.versionHistory[updated.versionHistory.length - 1]!.notes =
          notes;
      }
      await storage.set(`${PREFIX}${id}`, updated);
      await refresh();
    },
    [storage, refresh, templates],
  );

  const cloneTemplate = useCallback(
    async (id: string) => {
      const existing = templates.find((t) => t.id === id);
      if (!existing) return;
      const now = new Date().toISOString();
      const cloned: WordTemplate = {
        ...existing,
        id: uuid(),
        name: `${existing.name} (copie)`,
        clonedFrom: existing.id,
        versionHistory: [],
        createdAt: now,
        updatedAt: now,
      };
      await storage.set(`${PREFIX}${cloned.id}`, cloned);
      await refresh();
      return cloned;
    },
    [storage, refresh, templates],
  );

  const removeTemplate = useCallback(
    async (id: string) => {
      await storage.delete(`${PREFIX}${id}`);
      await refresh();
    },
    [storage, refresh],
  );

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

  const filteredTemplates = templates.filter((t) => {
    if (filters.category !== "all" && t.category !== filters.category)
      return false;
    if (filters.company !== "all" && t.company !== filters.company)
      return false;
    if (filters.search) {
      const q = filters.search.toLowerCase();
      return (
        t.name.toLowerCase().includes(q) ||
        t.description.toLowerCase().includes(q)
      );
    }
    return true;
  });

  return {
    templates: filteredTemplates,
    allTemplates: templates,
    loading,
    filters,
    updateFilter,
    addTemplate,
    updateTemplate,
    createRevision,
    cloneTemplate,
    removeTemplate,
    refresh,
  };
}
