"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";

type Day = "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun";
type MealType = "breakfast" | "lunch" | "dinner" | "snack";

const DAYS: Day[] = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
const MEAL_TYPES: MealType[] = ["breakfast", "lunch", "dinner", "snack"];

type Entry = {
  id: string;
  day: Day;
  mealType: MealType;
  servings: number;
  recipe: { id: string; title: string } | null;
};

type UserRecipe = { id: string; title: string };

export function SharedMealPlanView({
  mealPlanId,
  initialEntries,
  userRecipes,
  canEdit,
}: {
  mealPlanId: string;
  initialEntries: Entry[];
  userRecipes: UserRecipe[];
  canEdit: boolean;
}) {
  const t = useTranslations("mealPlan");
  const [entries, setEntries] = useState<Entry[]>(initialEntries);
  const [addingCell, setAddingCell] = useState<string | null>(null);

  // Live updates: other collaborators (or the owner, via the separate
  // MealPlanner component on their own /meal-plan page) can edit this same
  // plan — poll and merge, guarding this tab's own in-flight edits, same
  // pattern as shopping-list-view.tsx.
  const dirtyUntilRef = useRef<Map<string, number>>(new Map());
  const pendingDeleteIdsRef = useRef<Set<string>>(new Set());
  const DIRTY_MS = 4000;

  const markDirty = useCallback((id: string) => {
    dirtyUntilRef.current.set(id, Date.now() + DIRTY_MS);
  }, []);

  useEffect(() => {
    const interval = setInterval(() => {
      fetch(`/api/v1/meal-plans/shared/${mealPlanId}/entries`)
        .then((res) => (res.ok ? res.json() : null))
        .then((data: { entries: Entry[] } | null) => {
          if (!data) return;
          const now = Date.now();
          setEntries((prev) => {
            const prevById = new Map(prev.map((e) => [e.id, e]));
            return data.entries
              .filter((s) => !pendingDeleteIdsRef.current.has(s.id))
              .map((s) => {
                const dirty = (dirtyUntilRef.current.get(s.id) ?? 0) > now;
                return dirty ? (prevById.get(s.id) ?? s) : s;
              });
          });
        })
        .catch(() => {});
    }, 4000);
    return () => clearInterval(interval);
  }, [mealPlanId]);

  function cellKey(day: Day, mealType: MealType) {
    return `${day}-${mealType}`;
  }

  async function addEntry(day: Day, mealType: MealType, recipeId: string) {
    const res = await fetch(`/api/v1/meal-plans/shared/${mealPlanId}/entries`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ day, mealType, recipeId, servings: 2 }),
    });
    if (!res.ok) { toast.error(t("addFailed")); return; }
    const { id } = await res.json() as { id: string };
    markDirty(id);
    const recipe = userRecipes.find((r) => r.id === recipeId) ?? null;
    setEntries((prev) => [
      ...prev.filter((e) => !(e.day === day && e.mealType === mealType)),
      { id, day, mealType, servings: 2, recipe },
    ]);
    setAddingCell(null);
  }

  async function removeEntry(entry: Entry) {
    pendingDeleteIdsRef.current.add(entry.id);
    const res = await fetch(`/api/v1/meal-plans/shared/${mealPlanId}/entries?entryId=${entry.id}`, {
      method: "DELETE",
    });
    if (!res.ok) {
      pendingDeleteIdsRef.current.delete(entry.id);
      toast.error(t("removeFailed"));
      return;
    }
    setEntries((prev) => prev.filter((e) => e.id !== entry.id));
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full border-collapse text-sm min-w-[640px]">
        <thead>
          <tr>
            <th className="text-left p-2 text-muted-foreground font-medium"></th>
            {DAYS.map((day) => (
              <th key={day} className="text-left p-2 text-muted-foreground font-medium capitalize">{day}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {MEAL_TYPES.map((mealType) => (
            <tr key={mealType} className="border-t">
              <td className="p-2 text-muted-foreground font-medium capitalize align-top">{mealType}</td>
              {DAYS.map((day) => {
                const entry = entries.find((e) => e.day === day && e.mealType === mealType);
                const key = cellKey(day, mealType);
                return (
                  <td key={key} className="p-2 align-top min-w-[120px]">
                    {entry ? (
                      <div className="flex items-start justify-between gap-1 rounded-lg border p-2">
                        <span className="text-xs">{entry.recipe?.title ?? "—"}</span>
                        {canEdit && (
                          <Button variant="ghost" size="icon" className="h-5 w-5 shrink-0" onClick={() => void removeEntry(entry)} aria-label={t("removeEntry")}>
                            <Trash2 className="h-3 w-3" />
                          </Button>
                        )}
                      </div>
                    ) : canEdit ? (
                      addingCell === key ? (
                        <Select onValueChange={(v) => void addEntry(day, mealType, v as string)}>
                          <SelectTrigger className="h-8 text-xs">
                            <SelectValue placeholder={t("pickRecipe")} />
                          </SelectTrigger>
                          <SelectContent>
                            {userRecipes.map((r) => (
                              <SelectItem key={r.id} value={r.id}>{r.title}</SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      ) : (
                        <button
                          className="w-full h-8 rounded-lg border border-dashed text-xs text-muted-foreground hover:bg-muted/30"
                          onClick={() => setAddingCell(key)}
                        >
                          {t("addEntry")}
                        </button>
                      )
                    ) : (
                      <span className="text-xs text-muted-foreground">—</span>
                    )}
                  </td>
                );
              })}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
