import type { SupabaseClient } from "@supabase/supabase-js";
import type {
  Comment,
  Feature,
  Note,
  NoteCategory,
  PageStatus,
  Signoff,
} from "@/lib/types";
import { signImagePaths } from "@/lib/data/projects";

interface NoteRow {
  id: string;
  feature_id: string;
  content: string;
  image_path: string | null;
  category: string;
  resolved: boolean;
  author_email: string | null;
  created_at: string;
}

interface CommentRow {
  id: string;
  note_id: string;
  content: string;
  image_path: string | null;
  author_email: string | null;
  created_at: string;
}

/** All features for a project, each with its notes + threaded comments. */
export async function getFeatures(
  supabase: SupabaseClient,
  projectId: string,
): Promise<Feature[]> {
  const { data: featureRows } = await supabase
    .from("features")
    .select("id, project_id, description, status, signoff, author_email, created_at")
    .eq("project_id", projectId)
    .order("position", { ascending: true })
    .order("created_at", { ascending: true });

  const features = featureRows ?? [];
  const featureIds = features.map((f) => f.id);
  if (featureIds.length === 0) return [];

  const { data: noteData } = await supabase
    .from("notes")
    .select(
      "id, feature_id, content, image_path, category, resolved, author_email, created_at",
    )
    .in("feature_id", featureIds)
    .order("created_at", { ascending: true });
  const noteRows = (noteData as NoteRow[] | null) ?? [];

  const noteIds = noteRows.map((n) => n.id);
  let commentRows: CommentRow[] = [];
  if (noteIds.length > 0) {
    const { data } = await supabase
      .from("comments")
      .select("id, note_id, content, image_path, author_email, created_at")
      .in("note_id", noteIds)
      .order("created_at", { ascending: true });
    commentRows = (data as CommentRow[] | null) ?? [];
  }

  const signedUrls = await signImagePaths(supabase, [
    ...noteRows.flatMap((n) => (n.image_path ? [n.image_path] : [])),
    ...commentRows.flatMap((c) => (c.image_path ? [c.image_path] : [])),
  ]);

  const commentsByNote = new Map<string, Comment[]>();
  for (const c of commentRows) {
    const comment: Comment = {
      id: c.id,
      note_id: c.note_id,
      content: c.content,
      image_url: c.image_path ? signedUrls.get(c.image_path) ?? null : null,
      author_email: c.author_email,
      created_at: c.created_at,
    };
    const list = commentsByNote.get(c.note_id) ?? [];
    list.push(comment);
    commentsByNote.set(c.note_id, list);
  }

  const notesByFeature = new Map<string, Note[]>();
  for (const n of noteRows) {
    const note: Note = {
      id: n.id,
      page_id: null,
      feature_id: n.feature_id,
      content: n.content,
      image_url: n.image_path ? signedUrls.get(n.image_path) ?? null : null,
      category: n.category as NoteCategory,
      resolved: n.resolved,
      author_email: n.author_email,
      created_at: n.created_at,
      comments: commentsByNote.get(n.id) ?? [],
    };
    const list = notesByFeature.get(n.feature_id) ?? [];
    list.push(note);
    notesByFeature.set(n.feature_id, list);
  }

  return features.map((f) => ({
    id: f.id,
    project_id: f.project_id,
    description: f.description,
    status: f.status as PageStatus,
    signoff: f.signoff as Signoff,
    author_email: f.author_email,
    created_at: f.created_at,
    notes: notesByFeature.get(f.id) ?? [],
  }));
}
