import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { axiosInstance } from '../../../axiosApi';
import { AnalyticsEvents, trackEvent } from '../../utils/analytics';
import {
  canOpenBillingPortal,
  formatBillingDate,
  formatTokenCount,
  isComplimentarySubscription,
  SubscriptionMe,
} from '../../utils/finance';
import type { FinanceInvoice } from '../../utils/finance';

const GlassCard = styled.div`
  background: ${({ theme }) => theme.colors.cardBackground};
  backdrop-filter: blur(10px);
  border: 1px solid ${({ theme }) => theme.colors.cardBorder};
  border-radius: 1rem;
  padding: 2rem;
  width: 100%;
  max-width: 1000px;
  margin-bottom: 2rem;
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
`;

const CardTitle = styled.h2`
  font-size: 1.8rem;
  margin: 0 0 0.35rem 0;
  color: ${({ theme }) => theme.colors.text};
`;

const PlanName = styled.p`
  margin: 0 0 1.75rem 0;
  font-size: 1rem;
  font-weight: 600;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.85;
`;

const MeterBlock = styled.div`
  margin-bottom: 1.5rem;

  &:last-of-type {
    margin-bottom: 0;
  }
`;

const MeterHeader = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.55rem;
`;

const MeterLabel = styled.span`
  font-size: 1rem;
  font-weight: 600;
  color: ${({ theme }) => theme.colors.text};
`;

const MeterMeta = styled.span`
  font-size: 0.85rem;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.65;
  white-space: nowrap;
`;

const Track = styled.div`
  width: 100%;
  height: 0.55rem;
  border-radius: 999px;
  background: ${({ theme }) =>
    theme.darkMode ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.1)'};
  overflow: hidden;
`;

const Fill = styled.div<{ $pct: number; $warn: boolean }>`
  height: 100%;
  width: ${({ $pct }) => `${Math.min(100, Math.max(0, $pct))}%`};
  border-radius: 999px;
  background: ${({ theme, $warn }) => ($warn ? '#e67e22' : theme.main)};
  transition: width 0.35s ease;
`;

const MeterFooter = styled.div`
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.65;
`;

const BodyText = styled.p`
  margin: 0;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.75;
  line-height: 1.5;
`;

const UpgradeHint = styled.p`
  margin: 1.5rem 0 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid ${({ theme }) => theme.colors.cardBorder};
  font-size: 0.9rem;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.7;
  line-height: 1.45;
`;

const UpgradeButton = styled.button`
  margin-top: 1rem;
  background: ${({ theme }) => theme.main};
  border: none;
  border-radius: 0.5rem;
  color: #fff;
  padding: 0.7rem 1.25rem;
  font-weight: 600;
  cursor: pointer;

  &:hover {
    transform: translateY(-1px);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
  }
`;

function clampPct(used: number, quota: number): number {
  if (quota <= 0) return 0;
  return Math.min(100, Math.round((used / quota) * 1000) / 10);
}

type MeterProps = {
  label: string;
  meta: string;
  usedLabel: string;
  pct: number | null;
};

const UsageMeter = ({ label, meta, usedLabel, pct }: MeterProps): JSX.Element => {
  const showBar = pct !== null;
  const warn = showBar && pct >= 90;

  return (
    <MeterBlock>
      <MeterHeader>
        <MeterLabel>{label}</MeterLabel>
        <MeterMeta>{meta}</MeterMeta>
      </MeterHeader>
      <Track aria-hidden={!showBar}>
        {showBar ? <Fill $pct={pct} $warn={warn} /> : null}
      </Track>
      <MeterFooter>
        <span>{usedLabel}</span>
        <span>{showBar ? `${pct}%` : '—'}</span>
      </MeterFooter>
    </MeterBlock>
  );
};

const UsageSummaryCard = (): JSX.Element => {
  const [subscription, setSubscription] = useState<SubscriptionMe | null>(null);
  const [hasPortalAccess, setHasPortalAccess] = useState(false);
  const [loading, setLoading] = useState(true);
  const [upgradeLoading, setUpgradeLoading] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [subscriptionResponse, invoiceResponse] = await Promise.all([
        axiosInstance.get<SubscriptionMe>('/monetization/subscription/'),
        axiosInstance.get<FinanceInvoice[]>('/monetization/invoices/'),
      ]);
      setSubscription(subscriptionResponse.data || null);
      setHasPortalAccess(
        canOpenBillingPortal(
          Array.isArray(invoiceResponse.data) ? invoiceResponse.data : []
        )
      );
    } catch {
      setSubscription(null);
      setHasPortalAccess(false);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  const usage = subscription?.usage;
  const promptQuota = usage?.prompt_quota ?? null;
  const promptsUsed = usage?.prompts_in_window ?? 0;
  const promptPct =
    promptQuota !== null ? clampPct(promptsUsed, promptQuota) : null;

  const tokenQuota = usage?.monthly_token_quota ?? null;
  const tokensUsed = usage?.tokens_total_period ?? null;
  const tokenPct =
    tokenQuota !== null && tokensUsed !== null
      ? clampPct(tokensUsed, tokenQuota)
      : tokenQuota !== null
        ? 0
        : null;

  const complimentary = isComplimentarySubscription(subscription, hasPortalAccess);
  const showUpgrade = Boolean(subscription?.plan) && hasPortalAccess && !complimentary;

  const handleUpgrade = async () => {
    trackEvent(AnalyticsEvents.SUBSCRIPTION_UPGRADE_STARTED, {
      source: 'usage_card',
    });
    const billing = document.querySelector('[data-testid="billing-section"]');
    if (billing) {
      billing.scrollIntoView({ behavior: 'smooth', block: 'start' });
      const buttons = Array.from(billing.querySelectorAll('button'));
      const upgrade = buttons.find((btn) =>
        /upgrade/i.test(btn.textContent || '')
      );
      upgrade?.focus();
      return;
    }
    setUpgradeLoading(true);
    try {
      const returnUrl = `${window.location.origin}/account/`;
      const response = await axiosInstance.post<{ portal_url: string }>(
        '/monetization/portal/',
        { return_url: returnUrl }
      );
      if (response.data?.portal_url) {
        trackEvent(AnalyticsEvents.BILLING_PORTAL_OPENED, { intent: 'upgrade' });
        window.location.assign(response.data.portal_url);
      }
    } finally {
      setUpgradeLoading(false);
    }
  };

  return (
    <GlassCard data-testid="usage-summary-card">
      <CardTitle>Usage limit</CardTitle>
      {loading ? (
        <BodyText>Loading usage…</BodyText>
      ) : !subscription?.plan ? (
        <BodyText>No active plan yet.</BodyText>
      ) : (
        <>
          <PlanName>{subscription.plan.name}</PlanName>

          <UsageMeter
            label="Prompts"
            meta={`Resets every ${usage?.window_hours ?? '—'}h`}
            usedLabel={
              promptQuota === null
                ? `${promptsUsed.toLocaleString()} used`
                : `${promptsUsed.toLocaleString()} / ${promptQuota.toLocaleString()}`
            }
            pct={promptPct}
          />

          {tokenQuota !== null ? (
            <UsageMeter
              label="Tokens this month"
              meta={
                usage?.period_end
                  ? `Resets ${formatBillingDate(usage.period_end)}`
                  : 'Calendar month'
              }
              usedLabel={
                tokensUsed === null
                  ? `— / ${tokenQuota.toLocaleString()}`
                  : `${formatTokenCount(tokensUsed)} / ${tokenQuota.toLocaleString()}`
              }
              pct={tokenPct}
            />
          ) : (
            <UsageMeter
              label="Tokens this period"
              meta={
                usage?.period_end
                  ? `Period ends ${formatBillingDate(usage.period_end)}`
                  : 'This month'
              }
              usedLabel={`in ${formatTokenCount(usage?.tokens_in_period ?? null)} · out ${formatTokenCount(usage?.tokens_out_period ?? null)}`}
              pct={null}
            />
          )}

          {showUpgrade ? (
            <>
              <UpgradeHint>
                Need more capacity? Upgrade your plan in Billing, or open upgrade
                below.
              </UpgradeHint>
              <UpgradeButton
                type="button"
                onClick={handleUpgrade}
                disabled={upgradeLoading}
              >
                {upgradeLoading ? 'Opening…' : 'Upgrade'}
              </UpgradeButton>
            </>
          ) : complimentary ? (
            <UpgradeHint>Complimentary access — usage limits follow your granted plan.</UpgradeHint>
          ) : (
            <UpgradeHint>
              Need more capacity? Manage or upgrade your plan in Billing below.
            </UpgradeHint>
          )}
        </>
      )}
    </GlassCard>
  );
};

export default UsageSummaryCard;
