import { useEffect, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useAuth } from "@/hooks/useAuth";
import { supabase } from "@/integrations/supabase/client";
import { actionId, type ActionStatus } from "@/lib/actionMonitor";
import type { Action, BriefingCore } from "@/lib/briefing.functions";
import type { Suggestion } from "@/lib/selfExamination.functions";

const STORAGE_KEY_MONITOR = "ledger.action_monitor.v1";
const STORAGE_KEY_CUSTOM = "ledger.custom_actions.v1";
const STORAGE_KEY_DISMISS = "ledger.dismissed_actions.v1";

export function dailyDismissKey(a: Pick<Action, "title">) {
  return `daily:${actionId(a)}`;
}
export function selfExamDismissKey(s: Suggestion, idx: number) {
  return `selfexam:${s.area}:${idx}:${s.finding.slice(0, 40)}`;
}

function readJSON<T>(key: string, fallback: T): T {
  if (typeof window === "undefined") return fallback;
  try {
    return JSON.parse(window.localStorage.getItem(key) || "null") ?? fallback;
  } catch {
    return fallback;
  }
}

function readMonitor(): Record<string, ActionStatus> {
  return readJSON(STORAGE_KEY_MONITOR, {} as Record<string, ActionStatus>);
}
function readCustomItems(): { id: string }[] {
  const arr = readJSON<unknown[]>(STORAGE_KEY_CUSTOM, []);
  return Array.isArray(arr) ? (arr as { id: string }[]) : [];
}
function readDismissed(): Record<string, number> {
  return readJSON(STORAGE_KEY_DISMISS, {} as Record<string, number>);
}

/**
 * Returns unified Action Plan totals across daily / custom / self-exam,
 * accounting for dismissed items.
 */
export function useActionPlanSummary(opts: { hotelId?: string | null }) {
  const { hotelId } = opts;
  const { user } = useAuth();
  const qc = useQueryClient();

  const [monitor, setMonitor] = useState(() => readMonitor());
  const [customItems, setCustomItems] = useState(() => readCustomItems());
  const [dismissed, setDismissed] = useState(() => readDismissed());

  useEffect(() => {
    const refresh = () => {
      setMonitor(readMonitor());
      setCustomItems(readCustomItems());
      setDismissed(readDismissed());
    };
    window.addEventListener("ledger:action-monitor", refresh);
    window.addEventListener("ledger:custom-actions", refresh);
    window.addEventListener("ledger:dismissed-actions", refresh);
    window.addEventListener("storage", refresh);
    return () => {
      window.removeEventListener("ledger:action-monitor", refresh);
      window.removeEventListener("ledger:custom-actions", refresh);
      window.removeEventListener("ledger:dismissed-actions", refresh);
      window.removeEventListener("storage", refresh);
    };
  }, []);

  let dailyActions: Action[] = [];
  if (hotelId) {
    const matches = qc.getQueriesData<BriefingCore>({ queryKey: ["briefing", "core", hotelId] });
    for (const [, data] of matches) {
      if (data?.actions?.length) {
        dailyActions = data.actions;
        break;
      }
    }
  }

  const examQ = useQuery({
    queryKey: ["self_exam_suggestions_summary", user?.id, hotelId],
    enabled: !!user && !!hotelId,
    staleTime: 60_000,
    queryFn: async () => {
      const { data, error } = await supabase
        .from("self_examinations")
        .select("suggestions")
        .eq("hotel_id", hotelId!)
        .order("updated_at", { ascending: false })
        .limit(1)
        .maybeSingle();
      if (error) throw error;
      return (data?.suggestions as Suggestion[] | undefined) ?? [];
    },
  });

  const activeDaily = dailyActions.filter((a) => !dismissed[dailyDismissKey(a)]);
  const examSuggestions = examQ.data ?? [];
  const activeExam = examSuggestions
    .map((s, i) => ({ s, i }))
    .filter(({ s, i }) => !dismissed[selfExamDismissKey(s, i)]);

  // Build the set of monitor IDs that belong to currently-active items only.
  // This prevents stale "done" entries (from yesterday's actions or removed
  // items) from inflating today's progress numbers.
  const activeIds = new Set<string>();
  for (const a of activeDaily) activeIds.add(actionId(a));
  for (const c of customItems) activeIds.add(c.id);
  for (const { s, i } of activeExam) activeIds.add(selfExamDismissKey(s, i));

  const total = activeDaily.length + customItems.length + activeExam.length;

  let trackedDone = 0;
  let trackedInProgress = 0;
  for (const k of activeIds) {
    const st = monitor[k];
    if (st === "done") trackedDone++;
    else if (st === "in_progress") trackedInProgress++;
  }
  const done = Math.min(total, trackedDone);
  const inProgress = Math.min(Math.max(0, total - done), trackedInProgress);
  const todo = Math.max(0, total - done - inProgress);
  const dismissedCount = Object.keys(dismissed).length;

  return { total, done, inProgress, todo, dismissed: dismissedCount };
}
