import "./vega-embed";
import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { TopLevelSpec } from "vega-lite";
import type { AgentMessage } from "../types";
import "vega-embed";
import { VisualizationSpec } from "vega-embed";

/**
 * Web component for rendering charts related to the timeline data
 * Displays cumulative cost over time and message timing visualization
 */
@customElement("sketch-charts")
export class SketchCharts extends LitElement {
  @property({ type: Array })
  messages: AgentMessage[] = [];

  @state()
  private chartData: { timestamp: Date; cost: number }[] = [];

  // We need to make the styles available to Vega-Embed when it's rendered
  static styles = css`
    :host {
      display: block;
      width: 100%;
    }

    .chart-container {
      padding: 20px;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
      margin-bottom: 20px;
    }

    .chart-section {
      margin-bottom: 30px;
    }

    .chart-section h3 {
      margin-top: 0;
      margin-bottom: 15px;
      font-size: 18px;
      color: #333;
      border-bottom: 1px solid #eee;
      padding-bottom: 8px;
    }

    .chart-content {
      width: 100%;
      min-height: 300px;
    }

    .loader {
      border: 4px solid #f3f3f3;
      border-radius: 50%;
      border-top: 4px solid #3498db;
      width: 40px;
      height: 40px;
      margin: 20px auto;
      animation: spin 2s linear infinite;
    }

    @keyframes spin {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
  `;

  constructor() {
    super();
    this.chartData = [];
  }

  @state()
  private dollarsPerHour: number | null = null;

  private calculateCumulativeCostData(
    messages: AgentMessage[],
  ): { timestamp: Date; cost: number }[] {
    if (!messages || messages.length === 0) {
      return [];
    }

    let cumulativeCost = 0;
    const data: { timestamp: Date; cost: number }[] = [];

    for (const message of messages) {
      if (message.timestamp && message.usage && message.usage.cost_usd) {
        const timestamp = new Date(message.timestamp);
        cumulativeCost += message.usage.cost_usd;

        data.push({
          timestamp,
          cost: cumulativeCost,
        });
      }
    }

    // Calculate dollars per hour if we have at least two data points
    if (data.length >= 2) {
      const startTime = data[0].timestamp;
      const endTime = data[data.length - 1].timestamp;
      const totalHours =
        (endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60);
      const totalCost = data[data.length - 1].cost;

      // Only calculate if we have a valid time span
      if (totalHours > 0) {
        this.dollarsPerHour = totalCost / totalHours;
      } else {
        this.dollarsPerHour = null;
      }
    } else {
      this.dollarsPerHour = null;
    }

    return data;
  }

  protected willUpdate(changedProperties: PropertyValues): void {
    if (changedProperties.has("messages")) {
      this.chartData = this.calculateCumulativeCostData(this.messages);
    }
  }

  private getMessagesChartSpec(): VisualizationSpec {
    try {
      const allMessages = this.messages;
      if (!Array.isArray(allMessages) || allMessages.length === 0) {
        return null;
      }

      // Sort messages chronologically
      allMessages.sort((a, b) => {
        const dateA = a.timestamp ? new Date(a.timestamp).getTime() : 0;
        const dateB = b.timestamp ? new Date(b.timestamp).getTime() : 0;
        return dateA - dateB;
      });

      // Create unique indexes for all messages
      const messageIndexMap = new Map<string, number>();
      let messageIdx = 0;

      // First pass: Process parent messages
      allMessages.forEach((msg, index) => {
        // Create a unique ID for each message to track its position
        const msgId = msg.timestamp ? msg.timestamp.toString() : `msg-${index}`;
        messageIndexMap.set(msgId, messageIdx++);
      });

      // Process tool calls from messages to account for filtered out tool messages
      const toolCallData: any[] = [];
      allMessages.forEach((msg) => {
        if (msg.tool_calls && msg.tool_calls.length > 0) {
          msg.tool_calls.forEach((toolCall) => {
            if (toolCall.result_message) {
              // Add this tool result message to our data
              const resultMsg = toolCall.result_message;

              // Important: use the original message's idx to maintain the correct order
              // The original message idx value is what we want to show in the chart
              if (resultMsg.idx !== undefined) {
                // If the tool call has start/end times, add it to bar data, otherwise to point data
                if (resultMsg.start_time && resultMsg.end_time) {
                  toolCallData.push({
                    type: "bar",
                    index: resultMsg.idx, // Use actual idx from message
                    message_type: "tool",
                    content: resultMsg.content || "",
                    tool_name: resultMsg.tool_name || toolCall.name || "",
                    tool_input: toolCall.input || "",
                    tool_result: resultMsg.tool_result || "",
                    start_time: new Date(resultMsg.start_time).toISOString(),
                    end_time: new Date(resultMsg.end_time).toISOString(),
                    message: JSON.stringify(resultMsg, null, 2),
                  });
                } else if (resultMsg.timestamp) {
                  toolCallData.push({
                    type: "point",
                    index: resultMsg.idx, // Use actual idx from message
                    message_type: "tool",
                    content: resultMsg.content || "",
                    tool_name: resultMsg.tool_name || toolCall.name || "",
                    tool_input: toolCall.input || "",
                    tool_result: resultMsg.tool_result || "",
                    time: new Date(resultMsg.timestamp).toISOString(),
                    message: JSON.stringify(resultMsg, null, 2),
                  });
                }
              }
            }
          });
        }
      });

      // Prepare data for messages with start_time and end_time (bar marks)
      const barData = allMessages
        .filter((msg) => msg.start_time && msg.end_time) // Only include messages with explicit start and end times
        .map((msg) => {
          // Parse start and end times
          const startTime = new Date(msg.start_time!);
          const endTime = new Date(msg.end_time!);

          // Use the message idx directly for consistent ordering
          const index = msg.idx;

          // Truncate content for tooltip readability
          const displayContent = msg.content
            ? msg.content.length > 100
              ? msg.content.substring(0, 100) + "..."
              : msg.content
            : "No content";

          // Prepare tool input and output for tooltip if applicable
          const toolInput = msg.input
            ? msg.input.length > 100
              ? msg.input.substring(0, 100) + "..."
              : msg.input
            : "";

          const toolResult = msg.tool_result
            ? msg.tool_result.length > 100
              ? msg.tool_result.substring(0, 100) + "..."
              : msg.tool_result
            : "";

          return {
            index: index,
            message_type: msg.type,
            content: displayContent,
            tool_name: msg.tool_name || "",
            tool_input: toolInput,
            tool_result: toolResult,
            start_time: startTime.toISOString(),
            end_time: endTime.toISOString(),
            message: JSON.stringify(msg, null, 2), // Full message for detailed inspection
          };
        });

      // Prepare data for messages with timestamps only (point marks)
      const pointData = allMessages
        .filter((msg) => msg.timestamp && !(msg.start_time && msg.end_time)) // Only messages with timestamp but without start/end times
        .map((msg) => {
          // Get the timestamp
          const timestamp = new Date(msg.timestamp!);

          // Use the message idx directly for consistent ordering
          const index = msg.idx;

          // Truncate content for tooltip readability
          const displayContent = msg.content
            ? msg.content.length > 100
              ? msg.content.substring(0, 100) + "..."
              : msg.content
            : "No content";

          // Prepare tool input and output for tooltip if applicable
          const toolInput = msg.input
            ? msg.input.length > 100
              ? msg.input.substring(0, 100) + "..."
              : msg.input
            : "";

          const toolResult = msg.tool_result
            ? msg.tool_result.length > 100
              ? msg.tool_result.substring(0, 100) + "..."
              : msg.tool_result
            : "";

          return {
            index: index,
            message_type: msg.type,
            content: displayContent,
            tool_name: msg.tool_name || "",
            tool_input: toolInput,
            tool_result: toolResult,
            time: timestamp.toISOString(),
            message: JSON.stringify(msg, null, 2), // Full message for detailed inspection
          };
        });

      // Add tool call data to the appropriate arrays
      const toolBarData = toolCallData
        .filter((d) => d.type === "bar")
        .map((d) => {
          delete d.type;
          return d;
        });

      const toolPointData = toolCallData
        .filter((d) => d.type === "point")
        .map((d) => {
          delete d.type;
          return d;
        });

      // Check if we have any data to display
      if (
        barData.length === 0 &&
        pointData.length === 0 &&
        toolBarData.length === 0 &&
        toolPointData.length === 0
      ) {
        return null;
      }

      // Calculate height based on number of unique messages
      const chartHeight = 20 * Math.min(allMessages.length, 25); // Max 25 visible at once

      // Create a layered Vega-Lite spec combining bars and points
      const messagesSpec: TopLevelSpec = {
        $schema: "https://vega.github.io/schema/vega-lite/v5.json",
        description: "Message Timeline",
        width: "container",
        height: chartHeight,
        layer: [],
      };

      // Add bar layer if we have bar data
      if (barData.length > 0 || toolBarData.length > 0) {
        const combinedBarData = [...barData, ...toolBarData];
        messagesSpec.layer.push({
          data: { values: combinedBarData },
          mark: {
            type: "bar",
            height: 16,
          },
          encoding: {
            x: {
              field: "start_time",
              type: "temporal",
              title: "Time",
              axis: {
                format: "%H:%M:%S",
                title: "Time",
                labelAngle: -45,
              },
            },
            x2: { field: "end_time" },
            y: {
              field: "index",
              type: "ordinal",
              title: "Message Index",
              axis: {
                grid: true,
              },
            },
            color: {
              field: "message_type",
              type: "nominal",
              title: "Message Type",
              legend: {},
            },
            tooltip: [
              { field: "message_type", type: "nominal", title: "Type" },
              { field: "tool_name", type: "nominal", title: "Tool" },
              {
                field: "start_time",
                type: "temporal",
                title: "Start Time",
                format: "%H:%M:%S.%L",
              },
              {
                field: "end_time",
                type: "temporal",
                title: "End Time",
                format: "%H:%M:%S.%L",
              },
              { field: "content", type: "nominal", title: "Content" },
              { field: "tool_input", type: "nominal", title: "Tool Input" },
              { field: "tool_result", type: "nominal", title: "Tool Result" },
            ],
          },
        });
      }

      // Add point layer if we have point data
      if (pointData.length > 0 || toolPointData.length > 0) {
        const combinedPointData = [...pointData, ...toolPointData];
        messagesSpec.layer.push({
          data: { values: combinedPointData },
          mark: {
            type: "point",
            size: 100,
            filled: true,
          },
          encoding: {
            x: {
              field: "time",
              type: "temporal",
              title: "Time",
              axis: {
                format: "%H:%M:%S",
                title: "Time",
                labelAngle: -45,
              },
            },
            y: {
              field: "index",
              type: "ordinal",
              title: "Message Index",
            },
            color: {
              field: "message_type",
              type: "nominal",
              title: "Message Type",
            },
            tooltip: [
              { field: "message_type", type: "nominal", title: "Type" },
              { field: "tool_name", type: "nominal", title: "Tool" },
              {
                field: "time",
                type: "temporal",
                title: "Timestamp",
                format: "%H:%M:%S.%L",
              },
              { field: "content", type: "nominal", title: "Content" },
              { field: "tool_input", type: "nominal", title: "Tool Input" },
              { field: "tool_result", type: "nominal", title: "Tool Result" },
            ],
          },
        });
      }
      return messagesSpec;
    } catch (error) {
      console.error("Error rendering messages chart:", error);
    }
  }

  render() {
    const costSpec = this.createCostChartSpec();
    const messagesSpec = this.getMessagesChartSpec();

    return html`
      <div class="chart-container" id="chartContainer">
        <div class="chart-section">
          <h3>
            Dollar Usage Over
            Time${this.dollarsPerHour !== null
              ? html` (Avg: $${this.dollarsPerHour.toFixed(2)}/hr)`
              : ""}
          </h3>
          <div class="chart-content">
            ${this.chartData.length > 0
              ? html`<vega-embed .spec=${costSpec}></vega-embed>`
              : html`<p>No cost data available to display.</p>`}
          </div>
        </div>
        <div class="chart-section">
          <h3>Message Timeline</h3>
          <div class="chart-content">
            ${messagesSpec?.data
              ? html`<vega-embed .spec=${messagesSpec}></vega-embed>`
              : html`<p>No messages available to display.</p>`}
          </div>
        </div>
      </div>
    `;
  }

  private createCostChartSpec(): VisualizationSpec {
    return {
      $schema: "https://vega.github.io/schema/vega-lite/v5.json",
      description: "Cumulative cost over time",
      width: "container",
      height: 300,
      data: {
        values: this.chartData.map((d) => ({
          timestamp: d.timestamp.toISOString(),
          cost: d.cost,
        })),
      },
      mark: {
        type: "line",
        point: true,
      },
      encoding: {
        x: {
          field: "timestamp",
          type: "temporal",
          title: "Time",
          axis: {
            format: "%H:%M:%S",
            title: "Time",
            labelAngle: -45,
          },
        },
        y: {
          field: "cost",
          type: "quantitative",
          title: "Cumulative Cost (USD)",
          axis: {
            format: "$,.4f",
          },
        },
        tooltip: [
          {
            field: "timestamp",
            type: "temporal",
            title: "Time",
            format: "%Y-%m-%d %H:%M:%S",
          },
          {
            field: "cost",
            type: "quantitative",
            title: "Cumulative Cost",
            format: "$,.4f",
          },
        ],
      },
    };
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-charts": SketchCharts;
  }
}
