"use client";

import { useCallback, useEffect, useMemo, useState, type ReactNode } from "react";
import {
  Alert,
  Button,
  Card,
  Col,
  Progress,
  Row,
  Segmented,
  Space,
  Spin,
  Statistic,
  Tooltip,
  Typography,
} from "antd";
import { ArrowLeftOutlined, ReloadOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import { useParams, useRouter } from "next/navigation";

import { PageStateNotice } from "@/components/common/page-state-notice";
import { apiKeysApi, type APIKeyUsage, type UsageWindowDays } from "@/lib/api/api-keys";
import { extractApiErrorMessage } from "@/lib/api/errors";
import { useAuth } from "@/lib/hooks/use-auth";

const { Title, Paragraph, Text } = Typography;

const MANAGE_KEYS_PERMISSION = "agent:manage_own_keys";

const WINDOW_OPTIONS: Array<{ label: string; value: UsageWindowDays }> = [
  { label: "Last 7 Days", value: 7 },
  { label: "Last 30 Days", value: 30 },
];

function formatDateTime(value?: string | null) {
  return value ? dayjs(value).format("YYYY-MM-DD HH:mm") : null;
}

export default function APIKeyUsagePage() {
  const router = useRouter();
  const params = useParams<{ id: string }>();
  const keyId = params.id;
  const { hasPermission } = useAuth();
  const canManageKeys = hasPermission(MANAGE_KEYS_PERMISSION);

  const [days, setDays] = useState<UsageWindowDays>(30);
  const [usage, setUsage] = useState<APIKeyUsage | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);

  const loadUsage = useCallback(async () => {
    if (!canManageKeys || !/^\d+$/.test(keyId)) return;
    setLoading(true);
    try {
      const payload = await apiKeysApi.usage(keyId, days);
      setUsage(payload);
      setLoadError(null);
    } catch (error) {
      console.error("Failed to load API key usage", error);
      // Keep existing data on refresh failure; a first-load failure enters the error state.
      setLoadError(extractApiErrorMessage(error) ?? "API key usage could not be loaded.");
    } finally {
      setLoading(false);
    }
  }, [canManageKeys, days, keyId]);

  useEffect(() => {
    void loadUsage();
  }, [loadUsage]);

  // daily_counts only includes days with calls; zero-fill it into a continuous series.
  // The backend window is a rolling N days (created_at >= now - N days). The boundary
  // day may cover only part of the day but still counts toward total_calls, so the
  // series starts at today - N (N+1 bars) to keep the chart total equal to total_calls.
  const dailySeries = useMemo(() => {
    if (!usage) return [];
    const counts = new Map(usage.daily_counts.map((item) => [item.date, item.count]));
    const today = dayjs().startOf("day");
    const series: Array<{ date: string; count: number }> = [];
    for (let cursor = today.subtract(days, "day"); !cursor.isAfter(today); cursor = cursor.add(1, "day")) {
      const date = cursor.format("YYYY-MM-DD");
      series.push({ date, count: counts.get(date) ?? 0 });
    }
    return series;
  }, [usage, days]);

  const maxDailyCount = useMemo(
    () => dailySeries.reduce((max, item) => Math.max(max, item.count), 0),
    [dailySeries],
  );

  const backButton = (
    <Button icon={<ArrowLeftOutlined />} onClick={() => router.push("/dashboard/api-keys")}>
      Back to List
    </Button>
  );

  if (!canManageKeys) {
    return (
      <PageStateNotice
        tone="unavailable"
        title="API Key Usage Unavailable"
        description={`Your account is missing the ${MANAGE_KEYS_PERMISSION} permission required to view Agent API key usage. Contact an administrator to request access.`}
      />
    );
  }

  let content: ReactNode;
  if (!/^\d+$/.test(keyId)) {
    content = (
      <Card>
        <PageStateNotice
          tone="error"
          title="Invalid API Key ID"
          description={`"${keyId}" is not a valid API key ID. Go back to the list and open a key from there.`}
          actions={backButton}
        />
      </Card>
    );
  } else if (loading && !usage) {
    content = (
      <Card>
        <PageStateNotice tone="loading" title="Loading usage data" description="Aggregating call records from audit logs..." />
      </Card>
    );
  } else if (loadError && !usage) {
    content = (
      <Card>
        <PageStateNotice
          tone="error"
          title="Usage Data Failed to Load"
          description={loadError}
          actions={
            <Space wrap>
              <Button icon={<ReloadOutlined />} onClick={() => void loadUsage()}>
                Retry
              </Button>
              {backButton}
            </Space>
          }
        />
      </Card>
    );
  } else if (usage) {
    content = (
      <Spin spinning={loading}>
        <Space direction="vertical" size={16} style={{ width: "100%" }}>
          {loadError ? (
            <Alert
              type="error"
              showIcon
              closable
              message="Refresh failed. Showing data from the last successful load."
              description={loadError}
              onClose={() => setLoadError(null)}
            />
          ) : null}
          {usage.total_calls === 0 ? (
            <Card>
              <PageStateNotice
                tone="empty"
                title={`No calls in the last ${days} days`}
                description={
                  usage.last_used_at
                    ? `The last call was at ${formatDateTime(usage.last_used_at)}, before the current window${
                        days === 7 ? "; switch to the 30-day window to see it" : ""
                      }.`
                    : "This key has not been called since it was created."
                }
                actions={backButton}
              />
            </Card>
          ) : (
            <>
              <Row gutter={[16, 16]}>
                <Col xs={24} sm={12}>
                  <Card>
                    <Statistic title={`Total calls (last ${days} days)`} value={usage.total_calls} />
                  </Card>
                </Col>
                <Col xs={24} sm={12}>
                  <Card>
                    <Statistic
                      title="Last used"
                      value={formatDateTime(usage.last_used_at) ?? "Never used"}
                    />
                  </Card>
                </Col>
              </Row>
              <Row gutter={[16, 16]}>
                <Col xs={24} lg={14}>
                  <Card title={`Daily calls (last ${days} days)`}>
                    <div style={{ display: "flex", alignItems: "flex-end", gap: 2, height: 160, paddingTop: 8 }}>
                      {dailySeries.map((item) => {
                        const heightPercent = maxDailyCount > 0 ? (item.count / maxDailyCount) * 100 : 0;
                        return (
                          <Tooltip key={item.date} title={`${item.date}: ${item.count.toLocaleString()} calls`}>
                            <div
                              style={{
                                flex: 1,
                                minWidth: 4,
                                height: `${item.count > 0 ? Math.max(heightPercent, 3) : 1}%`,
                                background: item.count > 0 ? "#1677ff" : "#f0f0f0",
                                borderRadius: "2px 2px 0 0",
                              }}
                            />
                          </Tooltip>
                        );
                      })}
                    </div>
                    <Space style={{ width: "100%", justifyContent: "space-between", marginTop: 8 }}>
                      <Text type="secondary">{dailySeries[0]?.date}</Text>
                      <Text type="secondary">{dailySeries[dailySeries.length - 1]?.date}</Text>
                    </Space>
                  </Card>
                </Col>
                <Col xs={24} lg={10}>
                  <Card title="Resource Type Breakdown">
                    <Space direction="vertical" size={12} style={{ width: "100%" }}>
                      {usage.resource_breakdown.map((item) => {
                        const percent =
                          usage.total_calls > 0 ? Math.round((item.count / usage.total_calls) * 100) : 0;
                        return (
                          <div key={item.resource_type}>
                            <Space style={{ width: "100%", justifyContent: "space-between", marginBottom: 4 }}>
                              <Text code>{item.resource_type}</Text>
                              <Text type="secondary">
                                {item.count.toLocaleString()} calls · {percent}%
                              </Text>
                            </Space>
                            <Progress percent={percent} showInfo={false} size="small" />
                          </div>
                        );
                      })}
                    </Space>
                  </Card>
                </Col>
              </Row>
            </>
          )}
        </Space>
      </Spin>
    );
  }

  return (
    <Space direction="vertical" size={24} style={{ width: "100%" }}>
      <Space align="baseline" style={{ justifyContent: "space-between", width: "100%" }}>
        <div>
          <Title level={3} style={{ marginBottom: 4 }}>
            API Key Usage
          </Title>
          <Paragraph type="secondary" style={{ margin: 0 }}>
            Call statistics for key #{keyId}, aggregated from audit logs.
          </Paragraph>
        </div>
        <Space wrap>
          <Segmented
            options={WINDOW_OPTIONS}
            value={days}
            onChange={(value) => setDays(value as UsageWindowDays)}
          />
          <Button icon={<ReloadOutlined />} onClick={() => void loadUsage()} disabled={loading}>
            Refresh
          </Button>
          {backButton}
        </Space>
      </Space>

      <Alert type="info" showIcon message="Usage data comes from audit logs and is retained for up to 90 days (audit.retention_days)." />

      {content}
    </Space>
  );
}
