import { createSignal, onMount, onCleanup } from "solid-js";
import { getRefreshInterval } from "../utils/timeUtils";
import type { WidgetSchema, WidgetSettings } from "../types/widget";

interface CryptoPriceProps {
  settings: WidgetSettings;
}

const fetchCooldowns = new Map<string, number>();
const priceCache = new Map<string, string>();
const errorCache = new Map<string, string>();

export function CryptoPrice(props: CryptoPriceProps) {
  const widgetKey = `${props.settings.symbol}-${props.settings.currency}`;
  const COOLDOWN_MS = 5000;

  const [price, setPrice] = createSignal<string>(
    priceCache.get(widgetKey) || "Loading...",
  );
  const [error, setError] = createSignal<string>(
    errorCache.get(widgetKey) || "",
  );

  const fetchPrice = async () => {
    const now = Date.now();
    const lastFetch = fetchCooldowns.get(widgetKey) || 0;

    if (now - lastFetch < COOLDOWN_MS) {
      const remaining = Math.round((COOLDOWN_MS - (now - lastFetch)) / 1000);
      console.log(`[CryptoPrice] COOLDOWN: ${remaining}s remaining`);
      return;
    }

    fetchCooldowns.set(widgetKey, now);
    console.log("[CryptoPrice] Fetching price...");

    try {
      const symbol = (props.settings.symbol as string) || "bitcoin";
      const currency = (props.settings.currency as string) || "USD";

      const response = await fetch(
        `https://api.coingecko.com/api/v3/simple/price?ids=${symbol.toLowerCase()}&vs_currencies=${currency.toLowerCase()}`,
      );

      if (!response.ok) {
        throw new Error("Failed to fetch price");
      }

      const data = await response.json();
      const priceValue = data[symbol.toLowerCase()]?.[currency.toLowerCase()];

      if (priceValue) {
        const formattedPrice = `${currency} ${priceValue.toLocaleString()}`;
        setPrice(formattedPrice);
        setError("");
        priceCache.set(widgetKey, formattedPrice);
        errorCache.delete(widgetKey);
      } else {
        setError("Price not found");
        errorCache.set(widgetKey, "Price not found");
      }
    } catch (err) {
      setError("Error fetching price");
      errorCache.set(widgetKey, "Error fetching price");
      console.error("[CryptoPrice] Error:", err);
    }
  };

  onMount(() => {
    if (!priceCache.has(widgetKey)) {
      fetchPrice();
    }

    const refreshInterval = getRefreshInterval(props.settings, 1, "minutes");
    const intervalId = setInterval(() => {
      fetchPrice();
    }, refreshInterval);

    onCleanup(() => {
      clearInterval(intervalId);
    });
  });

  return (
    <div
      style={{
        border: "1px solid var(--border)",
        padding: "1rem",
        width: "100%",
        height: "100%",
        "box-sizing": "border-box",
        display: "flex",
        "flex-direction": "column",
        "justify-content": "center",
        "align-items": "center",
        background: "var(--bg, #fff)",
      }}
    >
      <div
        style={{
          "margin-bottom": "0.5rem",
          "font-weight": "bold",
          "font-size": "clamp(0.7rem, 2vw + 0.5vh, 1.5rem)",
          "text-align": "center",
          "line-height": "1.3",
        }}
      >
        {props.settings.symbol || "BTC"}
      </div>
      <div
        style={{
          "font-size": "clamp(0.8rem, 3.5vw + 0.5vh, 2.5rem)",
          "font-weight": "bold",
          "text-align": "center",
          "word-break": "break-word",
          "line-height": "1.2",
        }}
      >
        {error() || price()}
      </div>
      {props.settings.showLabel && (
        <div
          style={{
            "margin-top": "0.5rem",
            color: "var(--gray)",
            "font-size": "clamp(0.6rem, 1.5vw + 0.5vh, 1rem)",
            "text-align": "center",
            "line-height": "1.4",
          }}
        >
          {props.settings.label || "Price"}
        </div>
      )}
    </div>
  );
}

export const cryptoPriceSchema: WidgetSchema = {
  name: "Crypto Price",
  description: "Display cryptocurrency price from CoinGecko API",
  settingsSchema: {
    symbol: {
      type: "string",
      label: "Crypto Symbol (e.g., bitcoin, ethereum)",
      default: "bitcoin",
      required: true,
    },
    currency: {
      type: "string",
      label: "Currency (e.g., USD, EUR)",
      default: "USD",
      required: true,
    },
    refreshIntervalValue: {
      type: "number",
      label: "Refresh Interval",
      default: 1,
      required: true,
    },
    refreshIntervalUnit: {
      type: "select",
      label: "Unit",
      options: ["seconds", "minutes", "hours", "days"],
      default: "minutes",
      required: true,
    },
    showLabel: {
      type: "boolean",
      label: "Show Label",
      default: true,
    },
    label: {
      type: "string",
      label: "Custom Label",
      default: "Price",
    },
  },
};
