export function mount({ root, state, host }) {
  state = state || {};
  const __cleanup = [];
  const __setInterval = (...args) => {
    const id = window.setInterval(...args);
    __cleanup.push(() => window.clearInterval(id));
    return id;
  };
  const __setTimeout = (...args) => {
    const id = window.setTimeout(...args);
    __cleanup.push(() => window.clearTimeout(id));
    return id;
  };
  if (!(root instanceof HTMLElement)) return;

  const statusEl = root.querySelector("[data-cal-status]");
  const subtitleEl = root.querySelector("[data-cal-subtitle]");
  const dateEl = root.querySelector("[data-cal-date]");
  const listEl = root.querySelector("[data-cal-list]");
  const emptyEl = root.querySelector("[data-cal-empty]");
  const updatedEl = root.querySelector("[data-cal-updated]");

  if (!(statusEl instanceof HTMLElement) || !(subtitleEl instanceof HTMLElement) || !(dateEl instanceof HTMLElement) ||
      !(listEl instanceof HTMLElement) || !(emptyEl instanceof HTMLElement) || !(updatedEl instanceof HTMLElement)) {
    return;
  }

  const configuredToolName = typeof state.tool_name === 'string' ? state.tool_name.trim() : '';
  const configuredCalendarNames = Array.isArray(state.calendar_names)
    ? state.calendar_names.map((value) => String(value || '').trim()).filter(Boolean)
    : [];
  const refreshMsRaw = Number(state.refresh_ms);
  const REFRESH_MS = Number.isFinite(refreshMsRaw) && refreshMsRaw >= 60000 ? refreshMsRaw : 15 * 60 * 1000;

  const setStatus = (label, color) => {
    statusEl.textContent = label;
    statusEl.style.color = color;
  };

  const updateLiveContent = (snapshot) => {
    host.setLiveContent(snapshot);
  };

  const dayBounds = () => {
    const now = new Date();
    const start = new Date(now);
    start.setHours(0, 0, 0, 0);
    const end = new Date(now);
    end.setHours(23, 59, 59, 999);
    return { start, end };
  };

  const formatDateHeader = () => {
    const now = new Date();
    return now.toLocaleDateString([], { weekday: "long", month: "short", day: "numeric", year: "numeric" });
  };

  const normalizeDateValue = (value) => {
    if (typeof value === "string") return value;
    if (value && typeof value === "object") {
      if (typeof value.dateTime === "string") return value.dateTime;
      if (typeof value.date === "string") return value.date;
    }
    return "";
  };

  const formatTime = (value) => {
    const raw = normalizeDateValue(value);
    if (!raw) return "--:--";
    if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) return "All day";
    const d = new Date(raw);
    if (Number.isNaN(d.getTime())) return "--:--";
    return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  };

  const isAllDay = (start, end) => {
    const s = normalizeDateValue(start);
    const e = normalizeDateValue(end);
    return /^\d{4}-\d{2}-\d{2}$/.test(s) || /^\d{4}-\d{2}-\d{2}$/.test(e);
  };

  const eventSortKey = (evt) => {
    const raw = normalizeDateValue(evt && evt.start);
    const t = new Date(raw).getTime();
    return Number.isFinite(t) ? t : Number.MAX_SAFE_INTEGER;
  };

  const extractEvents = (toolResult) => {
    if (toolResult && toolResult.parsed && typeof toolResult.parsed === 'object') {
      const parsed = toolResult.parsed;
      if (Array.isArray(parsed.result)) return parsed.result;
    }
    if (typeof toolResult?.content === 'string') {
      try {
        const parsed = JSON.parse(toolResult.content);
        if (parsed && typeof parsed === 'object' && Array.isArray(parsed.result)) {
          return parsed.result;
        }
      } catch {
        return [];
      }
    }
    return [];
  };

  const resolveToolConfig = async () => {
    const fallbackName = configuredToolName || 'mcp_home_assistant_calendar_get_events';
    if (!host.listTools) {
      return { name: fallbackName, calendars: configuredCalendarNames };
    }
    try {
      const tools = await host.listTools();
      const tool = Array.isArray(tools)
        ? tools.find((item) => /(^|_)calendar_get_events$/i.test(String(item?.name || '')))
        : null;
      const enumValues = Array.isArray(tool?.parameters?.properties?.calendar?.enum)
        ? tool.parameters.properties.calendar.enum.map((value) => String(value || '').trim()).filter(Boolean)
        : [];
      return {
        name: tool?.name || fallbackName,
        calendars: configuredCalendarNames.length > 0 ? configuredCalendarNames : enumValues,
      };
    } catch {
      return { name: fallbackName, calendars: configuredCalendarNames };
    }
  };

  const renderEvents = (events) => {
    listEl.innerHTML = "";

    if (!Array.isArray(events) || events.length === 0) {
      emptyEl.style.display = "block";
      return;
    }

    emptyEl.style.display = "none";

    for (const evt of events) {
      const li = document.createElement("li");
      li.style.border = "1px solid var(--theme-card-neutral-border)";
      li.style.borderRadius = "10px";
      li.style.padding = "10px 12px";
      li.style.background = "#ffffff";

      const summary = document.createElement("div");
      summary.style.fontSize = "0.96rem";
      summary.style.fontWeight = "600";
      summary.style.color = "var(--theme-card-neutral-text)";
      summary.textContent = String(evt.summary || "(No title)");

      const timing = document.createElement("div");
      timing.style.marginTop = "4px";
      timing.style.fontSize = "0.86rem";
      timing.style.color = "var(--theme-card-neutral-subtle)";

      if (isAllDay(evt.start, evt.end)) {
        timing.textContent = "All day";
      } else {
        timing.textContent = `${formatTime(evt.start)} - ${formatTime(evt.end)}`;
      }

      li.appendChild(summary);
      li.appendChild(timing);

      if (evt.location) {
        const location = document.createElement("div");
        location.style.marginTop = "4px";
        location.style.fontSize = "0.84rem";
        location.style.color = "var(--theme-card-neutral-muted)";
        location.textContent = `Location: ${String(evt.location)}`;
        li.appendChild(location);
      }

      listEl.appendChild(li);
    }
  };

  const refresh = async () => {
    dateEl.textContent = formatDateHeader();
    setStatus("Refreshing", "var(--theme-status-muted)");

    try {
      const toolConfig = await resolveToolConfig();
      if (!toolConfig.name) throw new Error('Calendar tool unavailable');
      if (!Array.isArray(toolConfig.calendars) || toolConfig.calendars.length === 0) {
        subtitleEl.textContent = "No Home Assistant calendars available";
        renderEvents([]);
        updatedEl.textContent = new Date().toLocaleTimeString();
        setStatus("OK", "var(--theme-status-live)");
        updateLiveContent({
          kind: 'calendar_today',
          tool_name: toolConfig.name,
          calendar_names: [],
          updated_at: updatedEl.textContent || null,
          event_count: 0,
          events: [],
        });
        return;
      }

      subtitleEl.textContent = `${toolConfig.calendars.length} calendar${toolConfig.calendars.length === 1 ? "" : "s"}`;

      const allEvents = [];
      for (const calendarName of toolConfig.calendars) {
        const toolResult = await host.callTool(toolConfig.name, {
          calendar: calendarName,
          range: 'today',
        });
        const events = extractEvents(toolResult);
        for (const evt of events) {
          allEvents.push({ ...evt, _calendarName: calendarName });
        }
      }

      allEvents.sort((a, b) => eventSortKey(a) - eventSortKey(b));
      renderEvents(allEvents);
      updatedEl.textContent = new Date().toLocaleTimeString();
      setStatus("Daily", "var(--theme-status-live)");
      updateLiveContent({
        kind: 'calendar_today',
        tool_name: toolConfig.name,
        calendar_names: toolConfig.calendars,
        updated_at: updatedEl.textContent || null,
        event_count: allEvents.length,
        events: allEvents.map((evt) => ({
          summary: String(evt.summary || '(No title)'),
          start: normalizeDateValue(evt.start) || null,
          end: normalizeDateValue(evt.end) || null,
          location: typeof evt.location === 'string' ? evt.location : null,
          calendar_name: evt._calendarName || null,
        })),
      });
    } catch (err) {
      subtitleEl.textContent = "Could not load Home Assistant calendar";
      renderEvents([]);
      updatedEl.textContent = String(err);
      setStatus("Unavailable", "var(--theme-status-danger)");
      updateLiveContent({
        kind: 'calendar_today',
        tool_name: configuredToolName || 'mcp_home_assistant_calendar_get_events',
        calendar_names: configuredCalendarNames,
        updated_at: String(err),
        event_count: 0,
        events: [],
        error: String(err),
      });
    }
  };

  host.setRefreshHandler(() => {
    void refresh();
  });
  void refresh();
  __setInterval(() => {
    void refresh();
  }, REFRESH_MS);

  return {
    destroy() {
      host.setRefreshHandler(null);
      host.setLiveContent(null);
      host.clearSelection();
      for (const cleanup of __cleanup.splice(0)) cleanup();
    },
  };
}
