import {
  calculateStats,
  type BucketPoint,
  type MonitoringLogsResponse as BaseMonitoringLogsResponse,
} from "@/components/monitoring/monitoring-stats-row.tsx";
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@decocms/ui/components/chart.tsx";
import { computeTopErrors } from "./connection-health.ts";
import { KEYS } from "@/lib/query-keys.ts";
import { useStudioTools } from "@/lib/studio-tools";
import { useT } from "@/i18n/use-t.ts";
import { cn } from "@decocms/ui/lib/utils.ts";
import { useProjectContext } from "@/sdk";
import { useSuspenseQuery } from "@tanstack/react-query";
import { Suspense, useState } from "react";
import { Bar, BarChart, Cell } from "recharts";

type Timeframe = "7d" | "14d" | "30d";

const TIMEFRAMES: { value: Timeframe; label: string }[] = [
  { value: "7d", label: "7d" },
  { value: "14d", label: "14d" },
  { value: "30d", label: "30d" },
];

function getDateRange(timeframe: Timeframe): {
  startDate: Date;
  endDate: Date;
} {
  const end = new Date();
  const start = new Date(end);
  if (timeframe === "7d") start.setDate(start.getDate() - 7);
  else if (timeframe === "14d") start.setDate(start.getDate() - 14);
  else start.setDate(start.getDate() - 30);
  return { startDate: start, endDate: end };
}

const CHART_CONFIG = {
  calls: { label: "Tool calls" },
  errors: { label: "Errors" },
};

interface ActivityChartProps {
  connectionId: string;
  orgId: string;
  timeframe: Timeframe;
}

function ActivityChart({ connectionId, orgId, timeframe }: ActivityChartProps) {
  const t = useT();
  const studio = useStudioTools();
  const dateRange = getDateRange(timeframe);

  const { data } = useSuspenseQuery({
    queryKey: KEYS.connectionActivity(connectionId, timeframe, orgId),
    queryFn: async () => {
      return (await studio.call("MONITORING_LOGS_LIST", {
        startDate: dateRange.startDate.toISOString(),
        endDate: dateRange.endDate.toISOString(),
        connectionId,
        limit: 2000,
        offset: 0,
      })) as BaseMonitoringLogsResponse;
    },
    staleTime: 5 * 60 * 1000,
  });

  const stats = calculateStats(data?.logs ?? [], dateRange);
  const chartData = stats.data;
  const hasData = stats.totalCalls > 0;
  const topErrors = computeTopErrors(data?.logs ?? []);
  const errorRate =
    stats.totalCalls > 0
      ? Math.round((stats.totalErrors / stats.totalCalls) * 100)
      : 0;

  return (
    <div>
      {/* Summary numbers */}
      <div className="flex gap-6 px-5 pb-4">
        <div>
          <p className="text-2xl font-semibold text-foreground tabular-nums">
            {stats.totalCalls.toLocaleString()}
          </p>
          <p className="text-xs text-muted-foreground mt-0.5">
            {t("details.connectionActivity.toolCalls")}
          </p>
        </div>
        {stats.totalErrors > 0 && (
          <div>
            <p className="text-2xl font-semibold text-destructive tabular-nums">
              {stats.totalErrors.toLocaleString()}
            </p>
            <p className="text-xs text-muted-foreground mt-0.5">
              {t("details.connectionActivity.errors")}
            </p>
          </div>
        )}
        {stats.avgDurationMs > 0 && (
          <div>
            <p className="text-2xl font-semibold text-foreground tabular-nums">
              {Math.round(stats.avgDurationMs)}ms
            </p>
            <p className="text-xs text-muted-foreground mt-0.5">
              {t("details.connectionActivity.avgLatency")}
            </p>
          </div>
        )}
      </div>

      {hasData ? (
        <div>
          <ChartContainer config={CHART_CONFIG} className="h-16 w-full">
            <BarChart data={chartData} barCategoryGap="4%">
              <ChartTooltip
                content={
                  <ChartTooltipContent
                    labelFormatter={(_, payload) => {
                      const first = Array.isArray(payload)
                        ? payload[0]
                        : undefined;
                      return first &&
                        typeof first === "object" &&
                        "payload" in first
                        ? ((first as { payload?: { label?: string } }).payload
                            ?.label ?? "")
                        : "";
                    }}
                  />
                }
                cursor={{ fill: "var(--muted)" }}
              />
              <Bar dataKey="calls" radius={[2, 2, 0, 0]} minPointSize={1}>
                {chartData.map((entry: BucketPoint, index: number) => (
                  <Cell
                    key={`cell-${index}`}
                    fill={
                      entry.errorRate > 50
                        ? "var(--destructive)"
                        : "var(--chart-1)"
                    }
                    fillOpacity={
                      entry.calls === 0
                        ? 0.2
                        : entry.errorRate > 50
                          ? 0.7
                          : 0.85
                    }
                  />
                ))}
              </Bar>
            </BarChart>
          </ChartContainer>
          <div className="flex justify-between px-3 mt-1 pb-3">
            <span className="text-[10px] text-muted-foreground">
              {chartData[0]?.label}
            </span>
            <span className="text-[10px] text-muted-foreground">
              {chartData[chartData.length - 1]?.label}
            </span>
          </div>
        </div>
      ) : (
        <div className="h-20 flex items-center justify-center">
          <p className="text-sm text-muted-foreground/60">
            {t("details.connectionActivity.noActivityInThisPeriod")}
          </p>
        </div>
      )}

      {topErrors.length > 0 && (
        <div className="px-5 py-4 border-t border-border">
          <p className="text-xs font-medium text-muted-foreground mb-2">
            {t("details.connectionActivity.topErrors")}
            {errorRate > 0
              ? ` · ${t("details.connectionActivity.errorRatePercentage", {
                  errorRate: errorRate.toString(),
                })}`
              : ""}
          </p>
          <ul className="space-y-1.5">
            {topErrors.map((e) => (
              <li key={e.message} className="flex items-start gap-2 text-xs">
                <span className="tabular-nums text-destructive font-medium shrink-0">
                  {e.count.toLocaleString()}×
                </span>
                <span
                  className="text-muted-foreground truncate"
                  title={e.message}
                >
                  {e.message}
                </span>
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

function ActivitySkeleton() {
  return (
    <div>
      <div className="flex gap-6 px-5 pb-4">
        <div className="flex flex-col gap-1.5">
          <div className="h-7 w-16 rounded-md bg-muted animate-pulse" />
          <div className="h-3 w-14 rounded bg-muted animate-pulse" />
        </div>
      </div>
      <div className="h-20 w-full rounded-md bg-muted animate-pulse" />
    </div>
  );
}

interface ConnectionActivityProps {
  connectionId: string;
}

export function ConnectionActivity({ connectionId }: ConnectionActivityProps) {
  const t = useT();
  const [timeframe, setTimeframe] = useState<Timeframe>("14d");
  const { org } = useProjectContext();

  return (
    <div className="rounded-xl border border-border bg-card overflow-hidden">
      <div className="px-5 py-4 flex items-center justify-between">
        <div>
          <h3 className="text-sm font-semibold text-foreground">
            {t("details.connectionActivity.activity")}
          </h3>
        </div>
        <div className="flex items-center gap-0.5 bg-muted rounded-lg p-0.5">
          {TIMEFRAMES.map((tf) => (
            <button
              key={tf.value}
              type="button"
              onClick={() => setTimeframe(tf.value)}
              className={cn(
                "px-2.5 py-1 text-xs font-medium rounded-md transition-colors",
                timeframe === tf.value
                  ? "bg-background text-foreground shadow-sm"
                  : "text-muted-foreground hover:text-foreground",
              )}
            >
              {tf.label}
            </button>
          ))}
        </div>
      </div>
      <Suspense fallback={<ActivitySkeleton />}>
        <ActivityChart
          connectionId={connectionId}
          orgId={org.id}
          timeframe={timeframe}
        />
      </Suspense>
    </div>
  );
}
