"use client";

import { useCallback, useEffect, useState } from "react";
import { createClient, getBrowserUserId } from "@/lib/supabase/client";
import { useWorkspaceStore } from "@/stores/workspace-store";
import type { Priority, ProjectTemplate, ProjectTemplateTask } from "@/types";

interface TemplateTaskInput {
  title: string;
  description?: string;
  priority?: Priority;
  deadline_offset_days?: number | null;
}

interface TemplateInput {
  name: string;
  description?: string;
  goal?: string;
  color: string;
  icon: string;
  health: ProjectTemplate["health"];
  tasks: TemplateTaskInput[];
}

export function useProjectTemplates() {
  const [templates, setTemplates] = useState<ProjectTemplate[]>([]);
  const [loading, setLoading] = useState(true);
  const [userId, setUserId] = useState<string | null>(null);
  const supabase = createClient();
  const activeTeamId = useWorkspaceStore((state) => state.activeTeamId);
  const initialized = useWorkspaceStore((state) => state.initialized);

  useEffect(() => {
    void getBrowserUserId().then(setUserId).catch(() => setUserId(null));
  }, []);

  async function requireCurrentUserId() {
    const currentUserId = userId || (await getBrowserUserId());
    if (currentUserId && currentUserId !== userId) {
      setUserId(currentUserId);
    }
    return currentUserId;
  }

  const fetchTemplates = useCallback(async () => {
    if (!initialized) return;

    setLoading(true);

    let templatesQuery = supabase
      .from("project_templates")
      .select("*")
      .order("created_at", { ascending: false });

    templatesQuery = activeTeamId
      ? templatesQuery.eq("team_id", activeTeamId)
      : templatesQuery.is("team_id", null);

    const { data: templateRows, error: templateError } = await templatesQuery;
    if (templateError) throw templateError;

    const nextTemplates = (templateRows || []) as ProjectTemplate[];
    if (nextTemplates.length === 0) {
      setTemplates([]);
      setLoading(false);
      return;
    }

    const templateIds = nextTemplates.map((template) => template.id);
    let tasksQuery = supabase
      .from("project_template_tasks")
      .select("*")
      .in("template_id", templateIds)
      .order("sort_order")
      .order("created_at", { ascending: true });

    tasksQuery = activeTeamId
      ? tasksQuery.eq("team_id", activeTeamId)
      : tasksQuery.is("team_id", null);

    const { data: taskRows, error: taskError } = await tasksQuery;
    if (taskError) throw taskError;

    const tasksByTemplate = new Map<string, ProjectTemplateTask[]>();
    ((taskRows || []) as ProjectTemplateTask[]).forEach((task) => {
      const list = tasksByTemplate.get(task.template_id) || [];
      list.push(task);
      tasksByTemplate.set(task.template_id, list);
    });

    setTemplates(
      nextTemplates.map((template) => ({
        ...template,
        tasks: tasksByTemplate.get(template.id) || [],
      }))
    );
    setLoading(false);
  }, [activeTeamId, initialized, supabase]);

  useEffect(() => {
    if (!initialized) return;
    const timer = window.setTimeout(() => {
      void fetchTemplates();
    }, 0);

    return () => window.clearTimeout(timer);
  }, [fetchTemplates, initialized]);

  async function createTemplate(input: TemplateInput) {
    const currentUserId = await requireCurrentUserId();
    if (!currentUserId) throw new Error("Not authenticated");

    const { data: templateRow, error: templateError } = await supabase
      .from("project_templates")
      .insert({
        user_id: currentUserId,
        team_id: activeTeamId,
        name: input.name,
        description: input.description || "",
        goal: input.goal || "",
        color: input.color,
        icon: input.icon,
        health: input.health,
      })
      .select()
      .single();

    if (templateError) throw templateError;

    if (input.tasks.length > 0) {
      const { error: tasksError } = await supabase.from("project_template_tasks").insert(
        input.tasks.map((task, index) => ({
          template_id: templateRow.id,
          user_id: currentUserId,
          team_id: activeTeamId,
          title: task.title,
          description: task.description?.trim() || null,
          priority: task.priority || "none",
          deadline_offset_days:
            typeof task.deadline_offset_days === "number"
              ? task.deadline_offset_days
              : null,
          sort_order: index,
        }))
      );

      if (tasksError) throw tasksError;
    }

    await fetchTemplates();
    return templateRow as ProjectTemplate;
  }

  async function updateTemplate(id: string, input: TemplateInput) {
    const currentUserId = await requireCurrentUserId();
    if (!currentUserId) throw new Error("Not authenticated");

    const { error: templateError } = await supabase
      .from("project_templates")
      .update({
        name: input.name,
        description: input.description || "",
        goal: input.goal || "",
        color: input.color,
        icon: input.icon,
        health: input.health,
      })
      .eq("id", id);

    if (templateError) throw templateError;

    const { error: deleteError } = await supabase
      .from("project_template_tasks")
      .delete()
      .eq("template_id", id);

    if (deleteError) throw deleteError;

    if (input.tasks.length > 0) {
      const { error: tasksError } = await supabase.from("project_template_tasks").insert(
        input.tasks.map((task, index) => ({
          template_id: id,
          user_id: currentUserId,
          team_id: activeTeamId,
          title: task.title,
          description: task.description?.trim() || null,
          priority: task.priority || "none",
          deadline_offset_days:
            typeof task.deadline_offset_days === "number"
              ? task.deadline_offset_days
              : null,
          sort_order: index,
        }))
      );

      if (tasksError) throw tasksError;
    }

    await fetchTemplates();
  }

  async function deleteTemplate(id: string) {
    const { error } = await supabase.from("project_templates").delete().eq("id", id);
    if (error) throw error;
    setTemplates((prev) => prev.filter((template) => template.id !== id));
  }

  return {
    templates,
    loading,
    createTemplate,
    updateTemplate,
    deleteTemplate,
    refetch: fetchTemplates,
  };
}
