"use client";

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

interface MeetingTemplateInput {
  name: string;
  description?: string;
  duration_minutes: number;
  all_day: boolean;
  color?: string | null;
  participant_ids: string[];
}

export function useMeetingTemplates() {
  const [templates, setTemplates] = useState<MeetingTemplate[]>([]);
  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 query = supabase
      .from("meeting_templates")
      .select("*")
      .order("created_at", { ascending: false });

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

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

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

    const templateIds = nextTemplates.map((template) => template.id);
    const { data: participantRows, error: participantError } = await supabase
      .from("meeting_template_participants")
      .select("template_id, user_id, sort_order")
      .in("template_id", templateIds)
      .order("sort_order");

    if (participantError) throw participantError;

    const participantIds = Array.from(
      new Set((participantRows || []).map((row) => row.user_id))
    ) as string[];

    let profileMap = new Map<string, Profile>();
    if (participantIds.length > 0) {
      const { data: profiles, error: profileError } = await supabase
        .from("profiles")
        .select("id, email, full_name, avatar_url, created_at, updated_at")
        .in("id", participantIds);

      if (profileError) throw profileError;

      profileMap = new Map(
        ((profiles || []) as Profile[]).map((profile) => [profile.id, profile])
      );
    }

    const participantsByTemplate = new Map<string, Profile[]>();
    (participantRows || []).forEach((row) => {
      const profile = profileMap.get(row.user_id);
      if (!profile) return;
      const list = participantsByTemplate.get(row.template_id) || [];
      list.push(profile);
      participantsByTemplate.set(row.template_id, list);
    });

    setTemplates(
      nextTemplates.map((template) => ({
        ...template,
        participants: participantsByTemplate.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: MeetingTemplateInput) {
    const currentUserId = await requireCurrentUserId();
    if (!currentUserId) throw new Error("Not authenticated");

    const { data: templateRow, error: templateError } = await supabase
      .from("meeting_templates")
      .insert({
        user_id: currentUserId,
        team_id: activeTeamId,
        name: input.name.trim(),
        description: input.description?.trim() || "",
        duration_minutes: input.duration_minutes,
        all_day: input.all_day,
        color: input.color || null,
      })
      .select()
      .single();

    if (templateError) throw templateError;

    if (input.participant_ids.length > 0) {
      const { error: participantError } = await supabase
        .from("meeting_template_participants")
        .insert(
          input.participant_ids.map((participantId, index) => ({
            template_id: templateRow.id,
            user_id: participantId,
            team_id: activeTeamId,
            sort_order: index,
          }))
        );

      if (participantError) throw participantError;
    }

    await fetchTemplates();
    return templateRow as MeetingTemplate;
  }

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

    const { error: templateError } = await supabase
      .from("meeting_templates")
      .update({
        name: input.name.trim(),
        description: input.description?.trim() || "",
        duration_minutes: input.duration_minutes,
        all_day: input.all_day,
        color: input.color || null,
      })
      .eq("id", id);

    if (templateError) throw templateError;

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

    if (deleteError) throw deleteError;

    if (input.participant_ids.length > 0) {
      const { error: participantError } = await supabase
        .from("meeting_template_participants")
        .insert(
          input.participant_ids.map((participantId, index) => ({
            template_id: id,
            user_id: participantId,
            team_id: activeTeamId,
            sort_order: index,
          }))
        );

      if (participantError) throw participantError;
    }

    await fetchTemplates();
  }

  async function deleteTemplate(id: string) {
    const { error } = await supabase.from("meeting_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,
  };
}
