"use client";

import { useCallback, useEffect, useState } from "react";
import { createClient, getBrowserUser } from "@/lib/supabase/client";
import { useWorkspaceStore } from "@/stores/workspace-store";
import type {
  CommunicationKind,
  DirectMessage,
  DirectMessageStatus,
  TeamMessage,
} from "@/types";

export interface DirectMessageInput {
  recipient_email: string;
  kind: CommunicationKind;
  body?: string;
  task_title?: string;
  task_description?: string;
}

export interface TeamMessageInput {
  kind: CommunicationKind;
  body?: string;
  task_title?: string;
  task_description?: string;
}

export function useCommunication() {
  const [directMessages, setDirectMessages] = useState<DirectMessage[]>([]);
  const [teamMessages, setTeamMessages] = useState<TeamMessage[]>([]);
  const [loading, setLoading] = useState(true);
  const [userId, setUserId] = useState<string | null>(null);
  const [userEmail, setUserEmail] = useState<string | null>(null);
  const supabase = createClient();
  const activeTeamId = useWorkspaceStore((state) => state.activeTeamId);

  useEffect(() => {
    void getBrowserUser()
      .then((user) => {
        setUserId(user?.id ?? null);
        setUserEmail(user?.email?.toLowerCase() ?? null);
      })
      .catch(() => {
        setUserId(null);
        setUserEmail(null);
      });
  }, []);

  async function requireCurrentUser() {
    if (userId) return { id: userId, email: userEmail };
    const user = await getBrowserUser({ force: true });
    if (!user) throw new Error("Not authenticated");
    const normalizedEmail = user.email?.toLowerCase() ?? null;
    setUserId(user.id);
    setUserEmail(normalizedEmail);
    return { id: user.id, email: normalizedEmail };
  }

  const fetchCommunication = useCallback(async () => {
    setLoading(true);

    const directQuery = supabase
      .from("direct_messages")
      .select(
        "*, sender:profiles!direct_messages_sender_id_fkey(id, email, full_name, avatar_url, created_at, updated_at), recipient:profiles!direct_messages_recipient_id_fkey(id, email, full_name, avatar_url, created_at, updated_at)"
      )
      .order("created_at", { ascending: false })
      .limit(50);

    const teamQuery = activeTeamId
      ? supabase
          .from("team_messages")
          .select(
            "*, sender:profiles!team_messages_sender_id_fkey(id, email, full_name, avatar_url, created_at, updated_at)"
          )
          .eq("team_id", activeTeamId)
          .order("created_at", { ascending: false })
          .limit(50)
      : Promise.resolve({ data: [], error: null });

    const [directRes, teamRes] = await Promise.all([directQuery, teamQuery]);
    if (directRes.error) throw directRes.error;
    if (teamRes.error) throw teamRes.error;

    setDirectMessages((directRes.data || []) as DirectMessage[]);
    setTeamMessages((teamRes.data || []) as TeamMessage[]);
    setLoading(false);
  }, [activeTeamId, supabase]);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      void fetchCommunication().catch(() => setLoading(false));
    }, 0);

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

  async function sendDirectMessage(input: DirectMessageInput) {
    const currentUser = await requireCurrentUser();
    const { data, error } = await supabase
      .from("direct_messages")
      .insert({
        sender_id: currentUser.id,
        recipient_email: input.recipient_email.trim().toLowerCase(),
        kind: input.kind,
        body: input.body?.trim() || "",
        task_title: input.task_title?.trim() || "",
        task_description: input.task_description?.trim() || "",
      })
      .select()
      .single();

    if (error) throw error;
    setDirectMessages((prev) => [data as DirectMessage, ...prev]);
    return data as DirectMessage;
  }

  async function updateDirectMessageStatus(
    id: string,
    status: DirectMessageStatus,
    options?: { claimRecipient?: boolean }
  ) {
    const currentUser = await requireCurrentUser();
    const update: { status: DirectMessageStatus; recipient_id?: string } = { status };

    if (options?.claimRecipient) {
      update.recipient_id = currentUser.id;
    }

    const { data, error } = await supabase
      .from("direct_messages")
      .update(update)
      .eq("id", id)
      .select()
      .single();

    if (error) throw error;
    setDirectMessages((prev) =>
      prev.map((message) => (message.id === id ? (data as DirectMessage) : message))
    );
    return data as DirectMessage;
  }

  async function acceptDirectTask(message: DirectMessage) {
    const currentUser = await requireCurrentUser();
    const { data: task, error: taskError } = await supabase
      .from("tasks")
      .insert({
        user_id: currentUser.id,
        team_id: null,
        title: message.task_title || "Direct task request",
        description: message.task_description || message.body || null,
        status: "todo",
        priority: "none",
      })
      .select()
      .single();

    if (taskError) throw taskError;

    const { data, error } = await supabase
      .from("direct_messages")
      .update({
        status: "accepted",
        recipient_id: currentUser.id,
        created_task_id: task.id,
      })
      .eq("id", message.id)
      .select()
      .single();

    if (error) throw error;
    setDirectMessages((prev) =>
      prev.map((item) => (item.id === message.id ? (data as DirectMessage) : item))
    );
    return task;
  }

  async function sendTeamMessage(input: TeamMessageInput) {
    const currentUser = await requireCurrentUser();
    if (!activeTeamId) throw new Error("No active team selected");

    const { data, error } = await supabase
      .from("team_messages")
      .insert({
        team_id: activeTeamId,
        sender_id: currentUser.id,
        kind: input.kind,
        body: input.body?.trim() || "",
        task_title: input.task_title?.trim() || "",
        task_description: input.task_description?.trim() || "",
      })
      .select()
      .single();

    if (error) throw error;
    setTeamMessages((prev) => [data as TeamMessage, ...prev]);
    return data as TeamMessage;
  }

  async function createTaskFromTeamMessage(message: TeamMessage) {
    const currentUser = await requireCurrentUser();
    if (!activeTeamId) throw new Error("No active team selected");

    const { data: task, error: taskError } = await supabase
      .from("tasks")
      .insert({
        user_id: currentUser.id,
        team_id: activeTeamId,
        title: message.task_title || "Team task request",
        description: message.task_description || message.body || null,
        status: "todo",
        priority: "none",
      })
      .select()
      .single();

    if (taskError) throw taskError;

    const { data, error } = await supabase
      .from("team_messages")
      .update({ created_task_id: task.id })
      .eq("id", message.id)
      .select()
      .single();

    if (error) throw error;
    setTeamMessages((prev) =>
      prev.map((item) => (item.id === message.id ? (data as TeamMessage) : item))
    );
    return task;
  }

  return {
    directMessages,
    teamMessages,
    loading,
    userId,
    userEmail,
    activeTeamId,
    sendDirectMessage,
    updateDirectMessageStatus,
    acceptDirectTask,
    sendTeamMessage,
    createTaskFromTeamMessage,
    refetch: fetchCommunication,
  };
}
