<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { apiPost } from "@/api/client";
import type { ToolCallRecord } from "@/types/chat";

const props = defineProps<{
  toolCall: ToolCallRecord;
}>();

const appliedTags = ref<Set<string>>(new Set());
const applyingTag = ref<string | null>(null);

const label = computed(() => {
  if (props.toolCall.status === "declined") return "Declined";
  if (!props.toolCall.result.success) return "Error";
  switch (props.toolCall.result.type) {
    case "task":        return "Created task";
    case "note":        return "Created note";
    case "note_updated": return "Updated note";
    case "note_deleted": return "Deleted note";
    case "task_deleted": return "Deleted task";
    case "note_content": return "Note";
    case "notes_list":   return "Notes";
    case "tasks":        return "Tasks";
    case "todo_updated": return "Updated todo";
    case "search":       return "Searched notes";
    case "event":        return "Created event";
    case "events":       return "Found events";
    case "event_updated": return "Updated event";
    case "event_deleted": return "Deleted event";
    case "calendars":    return "Calendars";
    case "todo":         return "Created todo";
    case "todos":        return "Calendar todos";
    case "todo_completed": return "Completed todo";
    case "todo_deleted": return "Deleted todo";
    case "web_search":   return "Web search";
    case "research_pending": return "Research started";
    case "research_note":    return "Research note";
    case "image_search": return "Image search";
    default:             return "Tool call";
  }
});

const title = computed(() => {
  const data = props.toolCall.result.data;
  if (!data) return null;
  if (typeof data.title === "string") return data.title;
  return null;
});

const linkTo = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || typeof data.id !== "number") return null;
  return `/notes/${data.id}`;
});

const noteId = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || typeof data.id !== "number") return null;
  return data.id;
});

const suggestedTags = computed(() => props.toolCall.result.suggested_tags ?? []);

const eventData = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "event") return null;
  return data as { title: string; start: string; end: string };
});

const updatedEvent = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "event_updated") return null;
  return data as { title: string; start: string; end: string };
});

const deletedEvent = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "event_deleted") return null;
  return data as { title: string };
});

const calendarList = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "calendars") return null;
  const calendars = data.calendars as Array<{ name: string }> | undefined;
  return calendars?.map((c) => c.name) ?? [];
});

const todoData = computed(() => {
  const data = props.toolCall.result.data;
  const type = props.toolCall.result.type;
  if (!data || (type !== "todo" && type !== "todo_completed" && type !== "todo_deleted" && type !== "todo_updated")) return null;
  return data as { summary: string; due?: string; status?: string };
});

const todoList = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "todos") return null;
  return (data.todos as Array<{ summary: string; due?: string; status?: string }> | undefined) ?? [];
});

const todoCount = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "todos") return 0;
  return (data.count as number) ?? 0;
});

const eventList = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "events") return null;
  return (data.events as Array<{ title: string; start: string; end: string; location?: string }> | undefined) ?? [];
});

const eventCount = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "events") return 0;
  return (data.count as number) ?? 0;
});

function formatEventTime(iso: string): string {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleString(undefined, {
      weekday: "short", month: "short", day: "numeric",
      hour: "numeric", minute: "2-digit",
    });
  } catch { return iso; }
}

const taskList = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "tasks") return null;
  return (data.results as Array<{ id: number; title: string; status: string; priority: string; due_date?: string }> | undefined) ?? [];
});

const taskCount = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "tasks") return 0;
  return (data.total as number) ?? 0;
});

const webSearch = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "web_search") return null;
  return data as { query: string; results: { url: string; title: string; snippet: string }[]; count: number };
});

const searchResults = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "search") return null;
  const results = data.results as Array<{ id: number; title: string; type: string }> | undefined;
  return results && results.length > 0 ? results : null;
});

const deletedNote = computed(() => {
  const data = props.toolCall.result.data;
  const type = props.toolCall.result.type;
  if (!data || (type !== "note_deleted" && type !== "task_deleted")) return null;
  return data as { id: number; title: string };
});

const noteContent = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "note_content") return null;
  return data as { id: number; title: string; body: string; tags: string[] };
});

const noteList = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "notes_list") return null;
  return (data.results as Array<{ id: number; title: string; tags: string[]; preview: string }> | undefined) ?? [];
});

const noteListCount = computed(() => {
  const data = props.toolCall.result.data;
  if (!data || props.toolCall.result.type !== "notes_list") return 0;
  return (data.total as number) ?? 0;
});

// ── Collapse logic ───────────────────────────────────────────────────────────

// Cards with rich expandable content
const hasDetail = computed(() => {
  if (props.toolCall.status === "running") return false;
  return (
    (noteContent.value !== null && noteContent.value.tags.length > 0) ||
    (noteList.value !== null && noteList.value.length > 0) ||
    searchResults.value !== null ||
    (taskList.value !== null && taskList.value.length > 0) ||
    (eventList.value !== null && eventList.value.length > 0) ||
    (todoList.value !== null && todoList.value.length > 0) ||
    webSearch.value !== null ||
    (calendarList.value !== null && calendarList.value.length > 0) ||
    suggestedTags.value.length > 0
  );
});

// Collapsed by default for completed calls; errors and running stay open
const collapsed = ref(
  props.toolCall.status === "success" || props.toolCall.status === "declined"
);

// Auto-collapse when a running tool call completes
watch(() => props.toolCall.status, (s) => {
  if (s === "success") collapsed.value = true;
});

function toggle() {
  if (hasDetail.value) collapsed.value = !collapsed.value;
}

async function applyTag(tag: string) {
  if (!noteId.value || appliedTags.value.has(tag) || applyingTag.value) return;
  applyingTag.value = tag;
  try {
    await apiPost(`/api/notes/${noteId.value}/append-tag`, { tag });
    appliedTags.value.add(tag);
  } catch {
    // silently fail
  } finally {
    applyingTag.value = null;
  }
}
</script>

<template>
  <div
    class="tool-call-card"
    :class="{
      error: toolCall.status === 'error',
      declined: toolCall.status === 'declined',
      running: toolCall.status === 'running',
      collapsible: hasDetail,
    }"
  >
    <!-- ── Header row (always visible) ─────────────────────────── -->
    <div class="tool-card-header" :class="{ clickable: hasDetail }" @click="toggle">
      <span class="tool-label">{{ label }}</span>

      <!-- Inline summary content -->
      <template v-if="toolCall.status === 'declined'">
        <span class="tool-declined-name">
          {{ toolCall.arguments.title ?? toolCall.arguments.summary ?? toolCall.arguments.query ?? toolCall.function }}
        </span>
      </template>
      <template v-else-if="toolCall.status === 'error'">
        <span class="tool-error">{{ toolCall.result.error }}</span>
      </template>
      <template v-else-if="deletedNote">
        <span class="tool-deleted">{{ deletedNote.title || "Untitled" }}</span>
      </template>
      <template v-else-if="noteContent">
        <router-link :to="`/notes/${noteContent.id}`" class="tool-link" @click.stop>
          {{ noteContent.title || "Untitled" }}
        </router-link>
      </template>
      <template v-else-if="noteList !== null">
        <span class="tool-summary-count">{{ noteListCount }} found</span>
      </template>
      <template v-else-if="searchResults">
        <span class="tool-summary-count">
          {{ (toolCall.result.data?.count as number) ?? (toolCall.result.data?.total as number) ?? 0 }} found
        </span>
      </template>
      <template v-else-if="eventData">
        <span class="tool-event-title">{{ eventData.title }}</span>
        <span class="tool-event-time">{{ formatEventTime(eventData.start) }}</span>
      </template>
      <template v-else-if="updatedEvent">
        <span class="tool-event-title">{{ updatedEvent.title }}</span>
        <span class="tool-event-time">{{ formatEventTime(updatedEvent.start) }}</span>
      </template>
      <template v-else-if="deletedEvent">
        <span class="tool-deleted">{{ deletedEvent.title }}</span>
      </template>
      <template v-else-if="calendarList !== null">
        <span class="tool-summary-count">{{ calendarList.length }} calendar{{ calendarList.length !== 1 ? "s" : "" }}</span>
      </template>
      <template v-else-if="todoData">
        <span :class="{ 'tool-deleted': toolCall.result.type === 'todo_deleted', 'tool-completed': toolCall.result.type === 'todo_completed' }">
          {{ todoData.summary }}
        </span>
        <span v-if="todoData.due" class="tool-event-time">{{ formatEventTime(todoData.due) }}</span>
      </template>
      <template v-else-if="todoList !== null">
        <span class="tool-summary-count">{{ todoCount }} found</span>
      </template>
      <template v-else-if="taskList !== null">
        <span class="tool-summary-count">{{ taskCount }} found</span>
      </template>
      <template v-else-if="eventList !== null">
        <span class="tool-summary-count">{{ eventCount }} found</span>
      </template>
      <template v-else-if="webSearch">
        <span class="tool-summary-count">
          {{ webSearch.count }} result{{ webSearch.count !== 1 ? "s" : "" }}
        </span>
      </template>
      <template v-else-if="linkTo">
        <router-link :to="linkTo" class="tool-link" @click.stop>{{ title }}</router-link>
      </template>

      <!-- Chevron toggle -->
      <span v-if="hasDetail" class="tool-chevron" :class="{ open: !collapsed }">▶</span>
    </div>

    <!-- ── Detail section (expandable) ─────────────────────────── -->
    <div v-if="hasDetail" v-show="!collapsed" class="tool-card-detail">
      <template v-if="noteContent && noteContent.tags.length">
        <span class="tool-note-tags">
          <span v-for="tag in noteContent.tags" :key="tag" class="tool-note-tag">#{{ tag }}</span>
        </span>
      </template>

      <template v-else-if="noteList !== null && noteList.length > 0">
        <div class="tool-search-results">
          <router-link
            v-for="n in noteList.slice(0, 8)"
            :key="n.id"
            :to="`/notes/${n.id}`"
            class="tool-search-item"
          >{{ n.title || "Untitled" }}</router-link>
          <span v-if="noteList.length > 8" class="tool-event-more">+{{ noteList.length - 8 }} more</span>
        </div>
      </template>

      <template v-else-if="searchResults">
        <div class="tool-search-results">
          <router-link
            v-for="r in searchResults"
            :key="r.id"
            :to="`/notes/${r.id}`"
            class="tool-search-item"
          >{{ r.title || "Untitled" }}</router-link>
        </div>
      </template>

      <template v-else-if="todoList !== null && todoList.length > 0">
        <div class="tool-event-list">
          <div v-for="(t, i) in todoList.slice(0, 5)" :key="i" class="tool-event-item">
            <span class="tool-event-item-title">{{ t.summary }}</span>
            <span v-if="t.due" class="tool-event-item-time">{{ formatEventTime(t.due) }}</span>
          </div>
          <div v-if="todoList.length > 5" class="tool-event-more">+{{ todoList.length - 5 }} more</div>
        </div>
      </template>

      <template v-else-if="taskList !== null && taskList.length > 0">
        <div class="tool-event-list">
          <div v-for="(t, i) in taskList.slice(0, 5)" :key="i" class="tool-event-item">
            <router-link :to="`/tasks/${t.id}`" class="tool-event-item-title">{{ t.title }}</router-link>
            <span v-if="t.due_date" class="tool-event-item-time">{{ t.due_date }}</span>
            <span v-if="t.priority && t.priority !== 'none'" class="tool-task-priority" :class="`priority-${t.priority}`">{{ t.priority }}</span>
          </div>
          <div v-if="taskList.length > 5" class="tool-event-more">+{{ taskList.length - 5 }} more</div>
        </div>
      </template>

      <template v-else-if="eventList !== null && eventList.length > 0">
        <div class="tool-event-list">
          <div v-for="(ev, i) in eventList.slice(0, 5)" :key="i" class="tool-event-item">
            <span class="tool-event-item-title">{{ ev.title }}</span>
            <span class="tool-event-item-time">{{ formatEventTime(ev.start) }}</span>
          </div>
          <div v-if="eventList.length > 5" class="tool-event-more">+{{ eventList.length - 5 }} more</div>
        </div>
      </template>

      <template v-else-if="calendarList !== null">
        <div class="tool-calendar-list">
          <span v-for="name in calendarList" :key="name" class="tool-calendar-name">{{ name }}</span>
        </div>
      </template>

      <template v-else-if="webSearch">
        <div class="tool-search-results web-search-results">
          <a
            v-for="(r, i) in webSearch.results"
            :key="i"
            :href="r.url"
            target="_blank"
            rel="noopener noreferrer"
            class="tool-search-item"
          >{{ r.title || r.url }}</a>
        </div>
      </template>

      <!-- Suggested tags always at the bottom of detail -->
      <div v-if="suggestedTags.length > 0" class="tag-suggestions">
        <span class="tag-suggestions-label">Suggested tags:</span>
        <button
          v-for="tag in suggestedTags"
          :key="tag"
          :class="['tag-pill', { applied: appliedTags.has(tag) }]"
          :disabled="appliedTags.has(tag) || applyingTag === tag"
          @click="applyTag(tag)"
        >
          #{{ tag }}
          <span v-if="appliedTags.has(tag)" class="tag-check">&#10003;</span>
        </button>
      </div>
    </div>

    <!-- Suggested tags for non-detail cards (note/task created etc.) -->
    <div v-if="!hasDetail && suggestedTags.length > 0" class="tag-suggestions">
      <span class="tag-suggestions-label">Suggested tags:</span>
      <button
        v-for="tag in suggestedTags"
        :key="tag"
        :class="['tag-pill', { applied: appliedTags.has(tag) }]"
        :disabled="appliedTags.has(tag) || applyingTag === tag"
        @click="applyTag(tag)"
      >
        #{{ tag }}
        <span v-if="appliedTags.has(tag)" class="tag-check">&#10003;</span>
      </button>
    </div>
  </div>
</template>

<style scoped>
.tool-call-card {
  display: inline-block;
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  font-size: 0.8rem;
  margin-top: 0.4rem;
  overflow: hidden;
  vertical-align: top;
}
.tool-call-card.error {
  border-color: var(--color-danger, #e74c3c);
}
.tool-call-card.declined {
  opacity: 0.55;
}

/* ── Header ── */
.tool-card-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
}
.tool-card-header.clickable {
  cursor: pointer;
  user-select: none;
}
.tool-card-header.clickable:hover {
  background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}

.tool-label {
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.7rem;
  flex-shrink: 0;
}

.tool-chevron {
  font-size: 0.55rem;
  color: var(--color-text-muted);
  margin-left: auto;
  padding-left: 0.4rem;
  transition: transform 0.15s ease;
  flex-shrink: 0;
}
.tool-chevron.open {
  transform: rotate(90deg);
}

.tool-summary-count {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

/* ── Detail ── */
.tool-card-detail {
  padding: 0.3rem 0.6rem 0.45rem;
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

/* ── Shared content styles ── */
.tool-link {
  color: var(--color-primary);
  text-decoration: none;
}
.tool-link:hover { text-decoration: underline; }

.tool-error { color: var(--color-danger, #e74c3c); }

.tool-declined-name {
  text-decoration: line-through;
  color: var(--color-text-muted);
}

.tool-search-results {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.tool-search-item {
  color: var(--color-primary);
  text-decoration: none;
  font-size: 0.8rem;
}
.tool-search-item:hover { text-decoration: underline; }
.tool-search-item:not(:last-child)::after {
  content: ",";
  color: var(--color-text-muted);
  margin-right: 0.1rem;
}
.web-search-results {
  flex-direction: column;
  flex-wrap: nowrap;
}
.web-search-results .tool-search-item::after { content: none; }

.tool-event-title { font-weight: 600; color: var(--color-text); }
.tool-event-time { color: var(--color-text-muted); font-size: 0.75rem; }

.tool-event-list { display: flex; flex-direction: column; gap: 0.2rem; }
.tool-event-item { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.tool-event-item-title { color: var(--color-text); font-size: 0.8rem; }
.tool-event-item-time { color: var(--color-text-muted); font-size: 0.75rem; white-space: nowrap; }
.tool-event-more { color: var(--color-text-muted); font-size: 0.75rem; font-style: italic; }

.tool-deleted { text-decoration: line-through; opacity: 0.7; }
.tool-completed { text-decoration: line-through; color: var(--color-success, #2ecc71); }

.tool-note-tags { display: flex; flex-wrap: wrap; gap: 0.2rem; }
.tool-note-tag { font-size: 0.72rem; color: var(--color-text-muted); }

.tool-task-priority {
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; padding: 0.1rem 0.3rem; border-radius: 3px;
}
.priority-high { color: var(--color-danger, #e74c3c); }
.priority-medium { color: var(--color-warning, #f59e0b); }
.priority-low { color: var(--color-text-muted); }

.tool-calendar-list { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tool-calendar-name {
  display: inline-block; padding: 0.1rem 0.5rem;
  border-radius: 999px; background: var(--color-bg-secondary);
  border: 1px solid var(--color-border); font-size: 0.75rem; color: var(--color-text);
}

/* ── Tag suggestions ── */
.tag-suggestions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem;
  padding: 0.3rem 0.6rem; border-top: 1px solid var(--color-border);
}
.tool-call-card:not(:has(.tool-card-detail)) .tag-suggestions {
  /* When outside detail, no top border needed if it's the only extra content */
}
.tag-suggestions-label { font-size: 0.7rem; color: var(--color-text-muted); font-weight: 500; }

.tag-pill {
  display: inline-flex; align-items: center; gap: 0.2rem;
  padding: 0.15rem 0.5rem; border: 1px solid var(--color-primary);
  border-radius: 999px; background: transparent; color: var(--color-primary);
  font-size: 0.75rem; cursor: pointer; transition: background 0.15s, color 0.15s;
}
.tag-pill:hover:not(:disabled) { background: var(--color-primary); color: #fff; }
.tag-pill.applied {
  background: var(--color-success, #2ecc71); border-color: var(--color-success, #2ecc71);
  color: #fff; cursor: default;
}
.tag-pill:disabled:not(.applied) { opacity: 0.6; cursor: wait; }
.tag-check { font-size: 0.65rem; }
</style>
