import { type ReactNode, useEffect, useMemo, useState } from 'react';
import {
  Alert,
  Box,
  Button,
  CircularProgress,
  Divider,
  Link,
  Popover,
  Tooltip,
  Typography,
} from '@mui/material';
import PaidOutlinedIcon from '@mui/icons-material/PaidOutlined';
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
import { useSessionStore } from '@/store/sessionStore';
import {
  type HfAccountUsageBucket,
  type HfInferenceProvidersCredits,
  type UsageBucket,
  useUsageStore,
} from '@/store/usageStore';

function formatUsd(value: number | undefined): string {
  const amount = value ?? 0;
  if (amount > 0 && amount < 0.01) return '<$0.01';
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  }).format(amount);
}

function formatCount(value: number | undefined): string {
  return new Intl.NumberFormat('en-US').format(value ?? 0);
}

function contextTokenCount(telemetry: UsageBucket | null | undefined): number | undefined {
  if (!telemetry) return undefined;
  if (telemetry.total_tokens > 0) {
    return Math.max(0, telemetry.total_tokens - telemetry.completion_tokens);
  }
  return (
    telemetry.prompt_tokens +
    telemetry.cache_read_tokens +
    telemetry.cache_creation_tokens
  );
}

function billingUnavailableMessage(error: string | null | undefined): string | null {
  if (!error) return null;
  if (error === 'missing_hf_token') return 'Sign in to view HF account billing usage.';
  if (error === 'billing_usage_unavailable') {
    return 'HF billing usage is unavailable. Showing app-observed calls and tokens; inference cost may be incomplete.';
  }
  return 'HF billing usage is unavailable. Showing app-observed calls and tokens; inference cost may be incomplete.';
}

function UsageRow({
  label,
  value,
  strong = false,
}: {
  label: string;
  value: string;
  strong?: boolean;
}) {
  return (
    <>
      <Typography variant="body2" color="text.secondary">
        {label}
      </Typography>
      <Typography
        variant="body2"
        sx={{ fontWeight: strong ? 700 : 400, fontVariantNumeric: 'tabular-nums' }}
      >
        {value}
      </Typography>
    </>
  );
}

function UsageGrid({ children }: { children: ReactNode }) {
  return (
    <Box
      sx={{
        display: 'grid',
        gridTemplateColumns: '1fr auto',
        columnGap: 2,
        rowGap: 0.5,
        mt: 0.75,
      }}
    >
      {children}
    </Box>
  );
}

function AccountUsageSection({
  title,
  account,
  telemetry,
}: {
  title: string;
  account: HfAccountUsageBucket | null | undefined;
  telemetry: UsageBucket | null | undefined;
}) {
  const useJobEstimate =
    !account || (account.hf_jobs_usd <= 0 && (telemetry?.hf_jobs_estimated_usd ?? 0) > 0);

  return (
    <Box sx={{ py: 1 }}>
      <Typography variant="caption" sx={{ color: 'text.secondary', fontWeight: 700 }}>
        {title}
      </Typography>
      <UsageGrid>
        <UsageRow
          label="Inference Providers"
          value={account ? formatUsd(account.inference_providers_usd) : 'Unavailable'}
          strong
        />
        <UsageRow
          label="HF Jobs"
          value={formatUsd(
            useJobEstimate ? telemetry?.hf_jobs_estimated_usd : account?.hf_jobs_usd,
          )}
        />
        <UsageRow
          label="HF Sandboxes"
          value={formatUsd(telemetry?.sandbox_estimated_usd)}
        />
        <UsageRow label="LLM calls" value={formatCount(telemetry?.llm_calls)} />
        <UsageRow
          label="Input tokens"
          value={formatCount(contextTokenCount(telemetry))}
        />
        <UsageRow
          label="Output tokens"
          value={formatCount(telemetry?.completion_tokens)}
        />
      </UsageGrid>
    </Box>
  );
}

function CreditsSection({ credits }: { credits: HfInferenceProvidersCredits | null | undefined }) {
  if (!credits) return null;
  return (
    <>
      <Divider />
      <Box sx={{ py: 1 }}>
        <Typography variant="caption" sx={{ color: 'text.secondary', fontWeight: 700 }}>
          Inference credits
        </Typography>
        <UsageGrid>
          <UsageRow
            label="Included remaining"
            value={formatUsd(credits.remaining_included_usd)}
            strong
          />
          <UsageRow
            label="Used / included"
            value={`${formatUsd(credits.used_usd)} / ${formatUsd(credits.included_usd)}`}
          />
          {credits.limit_usd > 0 && (
            <UsageRow
              label="Spend limit remaining"
              value={formatUsd(credits.remaining_limit_usd)}
            />
          )}
        </UsageGrid>
      </Box>
    </>
  );
}

export default function UsageMeter() {
  const activeSessionId = useSessionStore((state) => state.activeSessionId);
  const activeSessionYoloSpend = useSessionStore((state) => {
    const active = state.sessions.find((session) => session.id === state.activeSessionId);
    return active?.autoApprovalEstimatedSpendUsd ?? null;
  });
  const { usage, isLoading, error, fetchUsage } = useUsageStore();
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);

  useEffect(() => {
    void fetchUsage(activeSessionId);
  }, [activeSessionId, activeSessionYoloSpend, fetchUsage]);

  const accountSessionInference =
    usage?.hf_account?.current_session?.inference_providers_usd;
  const sessionTotal =
    accountSessionInference == null
      ? usage?.session?.total_usd
      : accountSessionInference +
        (usage?.session?.hf_jobs_estimated_usd ?? 0) +
        (usage?.session?.sandbox_estimated_usd ?? 0);
  const links = useMemo(() => usage?.links ?? {}, [usage?.links]);
  const billingMessage = billingUnavailableMessage(usage?.hf_account?.error);
  const open = Boolean(anchorEl);

  return (
    <>
      <Tooltip title="Usage">
        <Button
          size="small"
          variant="outlined"
          startIcon={isLoading ? <CircularProgress size={14} /> : <PaidOutlinedIcon fontSize="small" />}
          onClick={(event) => setAnchorEl(event.currentTarget)}
          sx={{
            minWidth: { xs: 58, sm: 84 },
            height: 32,
            px: { xs: 0.75, sm: 1 },
            borderColor: 'divider',
            color: 'text.secondary',
            fontVariantNumeric: 'tabular-nums',
            '& .MuiButton-startIcon': { mr: { xs: 0.25, sm: 0.5 } },
            '&:hover': { borderColor: 'primary.main', color: 'primary.main' },
          }}
        >
          {sessionTotal == null ? 'Usage' : formatUsd(sessionTotal)}
        </Button>
      </Tooltip>
      <Popover
        open={open}
        anchorEl={anchorEl}
        onClose={() => setAnchorEl(null)}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
        transformOrigin={{ vertical: 'top', horizontal: 'right' }}
        slotProps={{
          paper: {
            sx: {
              width: 320,
              maxWidth: 'calc(100vw - 24px)',
              maxHeight: 'calc(100vh - 24px)',
              overflowY: 'auto',
              p: 2,
              border: '1px solid',
              borderColor: 'divider',
            },
          },
        }}
      >
        <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>
          Usage
        </Typography>
        <Typography variant="caption" color="text.secondary">
          Estimated from HF account usage per session.
        </Typography>

        {error ? (
          <Typography variant="body2" color="error" sx={{ mt: 1.5 }}>
            {error}
          </Typography>
        ) : (
          <>
            {billingMessage && (
              <Alert severity="info" sx={{ mt: 1.5, py: 0.25 }}>
                {billingMessage}
              </Alert>
            )}
            <AccountUsageSection
              title="Current session"
              account={usage?.hf_account?.current_session ?? null}
              telemetry={usage?.session ?? null}
            />
            <CreditsSection credits={usage?.hf_account?.inference_providers_credits} />
          </>
        )}

        <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, pt: 1 }}>
          {links.hf_billing && (
            <Link href={links.hf_billing} target="_blank" rel="noopener noreferrer" underline="hover" sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.25, fontSize: '0.75rem' }}>
              HF billing <OpenInNewIcon sx={{ fontSize: 12 }} />
            </Link>
          )}
          {links.jobs_pricing && (
            <Link href={links.jobs_pricing} target="_blank" rel="noopener noreferrer" underline="hover" sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.25, fontSize: '0.75rem' }}>
              Jobs pricing <OpenInNewIcon sx={{ fontSize: 12 }} />
            </Link>
          )}
        </Box>
      </Popover>
    </>
  );
}
