import { useEffect, useRef, useState } from 'react';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import TrendingDownIcon from '@mui/icons-material/TrendingDown';
import { Avatar, Box, Button, Collapse, Stack, Typography } from '@mui/material';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import {
  useCheckoutStatus,
  useLineItems,
  useBillingInterval,
  usePricingFeature,
  useExchangeRate,
  useSlippage,
  useSessionContext,
  usePaymentMethodContext,
  useProduct,
} from '@blocklet/payment-react-headless';

import { useMobile } from '../../../hooks/mobile';
import {
  INTERVAL_LOCALE_KEY,
  formatTrialText,
  getSessionHeaderMeta,
  tSafe,
  primaryContrastColor,
} from '../../utils/format';
import ProductItemCard from '../../components/left/product-item-card';
import BillingToggle from '../../components/left/billing-toggle';
import CrossSellCard from '../../components/left/cross-sell-card';
import ExchangeRateFooter from '../../components/shared/exchange-rate-footer';
import TrialInfo from '../../components/left/trial-info';

export default function CompositePanel() {
  const { t } = useLocaleContext();
  const { session } = useSessionContext();
  const { currency, isStripe, switching: currencySwitching } = usePaymentMethodContext();
  const { livemode } = useCheckoutStatus();
  const { product, pageInfo } = useProduct();
  const lineItems = useLineItems();
  const billingInterval = useBillingInterval();
  const pricing = usePricingFeature();
  const rate = useExchangeRate();
  const slippage = useSlippage();
  const { isMobile } = useMobile();

  const mode = session?.mode || 'payment';
  const discounts = (session as any)?.discounts || [];
  const appName = (session as any)?.app_name || (session as any)?.payment_link?.app_name || '';
  const appLogo = (session as any)?.app_logo || (session as any)?.payment_link?.app_logo || '';
  const showItemsCollapse = isMobile || lineItems.items.length >= 4;
  const [itemsExpanded, setItemsExpanded] = useState(
    isMobile ? lineItems.items.length <= 1 : lineItems.items.length < 4
  );

  // Detect cross-sell not yet added
  const crossSellNotAdded =
    lineItems.crossSellItem && !lineItems.items.some((i: any) => i.price_id === lineItems.crossSellItem?.id);

  // ── Find the single item with upsell → promote toggle to top ──
  // Backend rejects upsell when line_items > 1 (only cross-sell items are auto-removable).
  // So upsell is only possible when all other items are cross-sell.
  const nonCrossSellItems = lineItems.items.filter((i: any) => !i.cross_sell);
  const itemsWithUpsell = lineItems.items.filter((i: any) => (i.price as any)?.upsell?.upsells_to);
  const upsellPrimaryItem = itemsWithUpsell.length === 1 ? itemsWithUpsell[0] : null;
  const upsellTarget = upsellPrimaryItem ? (upsellPrimaryItem.price as any)?.upsell?.upsells_to : null;
  const canUpsell = nonCrossSellItems.length <= 1;
  const hasTopUpsell = canUpsell && !!upsellPrimaryItem && ['subscription', 'setup'].includes(mode);
  const isUpselled = !!(upsellPrimaryItem as any)?.upsell_price;
  const [upsellSwitching, setUpsellSwitching] = useState(false);
  // Optimistic: track which tab the user clicked so highlight switches immediately
  const [pendingUpsell, setPendingUpsell] = useState<boolean | null>(null);
  const visualIsUpselled = pendingUpsell !== null ? pendingUpsell : isUpselled;

  // Intervals for capsule toggle
  const currentInterval = hasTopUpsell ? (upsellPrimaryItem!.price as any)?.recurring?.interval : null;
  const upsellInterval = hasTopUpsell ? upsellTarget?.recurring?.interval : null;

  // Savings %
  let upsellSavings = 0;
  if (hasTopUpsell && currentInterval && upsellInterval) {
    const fromAmt = parseFloat(
      (upsellPrimaryItem!.price as any)?.base_amount || (upsellPrimaryItem!.price as any)?.unit_amount || '0'
    );
    const toAmt = parseFloat(upsellTarget?.base_amount || upsellTarget?.unit_amount || '0');
    const yearMap: Record<string, number> = { day: 365, week: 52, month: 12, year: 1 };
    const fromY = fromAmt * (yearMap[currentInterval] || 1);
    const toY = toAmt * (yearMap[upsellInterval] || 1);
    if (fromY > toY && fromY > 0) upsellSavings = Math.round(((fromY - toY) / fromY) * 100);
  }

  // Toast on rate failure (only once per transition to 'unavailable')
  const prevRateStatusRef = useRef(rate.status);
  useEffect(() => {
    if (prevRateStatusRef.current !== 'unavailable' && rate.status === 'unavailable' && !isStripe) {
      Toast.error(t('payment.dynamicPricing.unavailable.message'));
    }
    prevRateStatusRef.current = rate.status;
  }, [rate.status, isStripe, t]);

  // Structured header meta: badge, title, subtitle
  const headerMeta = getSessionHeaderMeta(t, session, product, lineItems.items);
  const isMultiItem = lineItems.items.length > 1;

  // Capsule button sx helper
  const activeSx = {
    bgcolor: 'primary.main',
    color: (theme: any) => primaryContrastColor(theme),
    boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)',
  };
  const inactiveSx = {
    color: 'text.secondary',
    '&:hover': { color: 'text.primary' },
  };
  const capsuleBtnSx = (active: boolean) => ({
    px: 3.5,
    py: 1,
    borderRadius: '9999px',
    cursor: 'pointer',
    transition: 'all 0.3s ease',
    userSelect: 'none' as const,
    ...(active ? activeSx : inactiveSx),
  });

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
      {/* App branding — desktop only (mobile uses compact inline) */}
      {!isMobile && (appName || appLogo) && (
        <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 5 }}>
          {appLogo && (
            <Avatar
              src={appLogo}
              alt={appName}
              sx={{
                width: 48,
                height: 48,
                borderRadius: '16px',
                bgcolor: 'background.paper',
                boxShadow: 1,
                border: '1px solid',
                borderColor: 'divider',
              }}
            />
          )}
          {appName && <Typography sx={{ fontWeight: 600, fontSize: 15, color: 'text.primary' }}>{appName}</Typography>}
        </Stack>
      )}

      {/* Top spacer — balances bottom spacer to vertically center main content (desktop only) */}
      {!isMobile && <Box sx={{ flexGrow: 1, flexShrink: 1, flexBasis: 0 }} />}

      {/* ── Top: header content (fixed, does not scroll) ── */}
      <Box sx={{ flexShrink: 0 }}>
        {/* Header section: type badge + title + subtitle */}
        <Box sx={{ mb: { xs: 3, md: 4 } }}>
          {/* Mobile: compact branding row */}
          {isMobile && (appName || appLogo) && (
            <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
              {appLogo && <Avatar src={appLogo} alt={appName} sx={{ width: 24, height: 24, borderRadius: '6px' }} />}
              {appName && (
                <Typography sx={{ fontWeight: 600, fontSize: 13, color: 'text.secondary' }}>{appName}</Typography>
              )}
            </Stack>
          )}

          {/* Type badge + trial tag + TEST MODE */}
          <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1.5 }}>
            <Typography
              component="span"
              sx={{
                fontSize: 10,
                fontWeight: 700,
                letterSpacing: '0.1em',
                lineHeight: 1,
                textTransform: 'uppercase',
                color: 'primary.main',
                bgcolor: (theme) =>
                  theme.palette.mode === 'dark' ? `${theme.palette.primary.main}1A` : `${theme.palette.primary.main}0D`,
                px: 1,
                py: 0.5,
                borderRadius: '4px',
              }}>
              {headerMeta.badgeLabel}
            </Typography>
            {pricing.trial.active && pricing.trial.days > 0 && (
              <Typography
                component="span"
                sx={{
                  fontSize: 10,
                  fontWeight: 700,
                  letterSpacing: '0.1em',
                  lineHeight: 1,
                  textTransform: 'uppercase',
                  color: 'primary.main',
                  bgcolor: (theme) =>
                    theme.palette.mode === 'dark'
                      ? `${theme.palette.primary.main}1A`
                      : `${theme.palette.primary.main}0D`,
                  px: 1,
                  py: 0.5,
                  borderRadius: '4px',
                }}>
                {formatTrialText(t, pricing.trial.days, pricing.trial.afterTrialInterval || 'day')}
              </Typography>
            )}
            {!livemode && (
              <Typography
                component="span"
                sx={{
                  fontSize: 10,
                  fontWeight: 700,
                  letterSpacing: '0.1em',
                  lineHeight: 1,
                  textTransform: 'uppercase',
                  color: (theme) => (theme.palette.mode === 'dark' ? theme.palette.grey[500] : theme.palette.grey[400]),
                  bgcolor: (theme) =>
                    theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.06)' : theme.palette.grey[100],
                  px: 1,
                  py: 0.5,
                  borderRadius: '4px',
                }}>
                {t('common.livemode')}
              </Typography>
            )}
          </Stack>

          {/* Title: product name (single item) or "Order Summary" (multi item) */}
          <Typography
            sx={{
              fontWeight: 800,
              fontSize: { xs: 24, md: 36 },
              lineHeight: 1.1,
              letterSpacing: '-0.03em',
              color: 'text.primary',
              mb: 0.75,
            }}>
            {isMultiItem ? tSafe(t, 'payment.checkout.orderSummary', 'Order Summary') : headerMeta.title}
          </Typography>

          {/* Subtitle */}
          {(isMultiItem || headerMeta.subtitle) && (
            <Typography
              sx={{
                color: 'text.secondary',
                fontSize: { xs: 14, md: 16 },
                fontWeight: 500,
                lineHeight: 1.5,
              }}>
              {isMultiItem
                ? tSafe(t, 'payment.checkout.orderSummarySubtitle', 'Items included in this purchase')
                : headerMeta.subtitle}
            </Typography>
          )}

          {/* ── Top-level upsell toggle (single subscription) ── */}
          {hasTopUpsell && (
            <Stack direction="row" alignItems="center" spacing={2} sx={{ mt: 2.5 }}>
              <Stack
                direction="row"
                alignItems="center"
                sx={{
                  bgcolor: 'background.paper',
                  borderRadius: '9999px',
                  border: '1px solid',
                  borderColor: 'divider',
                  p: '4px',
                  display: 'inline-flex',
                  boxShadow: (theme) =>
                    theme.palette.mode === 'dark' ? '0 1px 2px 0 rgba(0,0,0,0.3)' : '0 1px 2px 0 rgba(0,0,0,0.05)',
                }}>
                {/* Current interval */}
                <Box
                  onClick={async () => {
                    if (isUpselled && !upsellSwitching) {
                      setPendingUpsell(false);
                      setUpsellSwitching(true);
                      try {
                        await lineItems.downsell(
                          (upsellPrimaryItem as any).upsell_price?.id || upsellPrimaryItem!.price_id
                        );
                      } catch (err: any) {
                        setPendingUpsell(null);
                        Toast.error(err?.response?.data?.error || err?.message || 'Failed');
                      } finally {
                        setUpsellSwitching(false);
                        setPendingUpsell(null);
                      }
                    }
                  }}
                  sx={capsuleBtnSx(!visualIsUpselled)}>
                  <Typography component="span" sx={{ fontSize: 14, fontWeight: 700, color: 'inherit', lineHeight: 1 }}>
                    {t(INTERVAL_LOCALE_KEY[currentInterval!] || '')}
                  </Typography>
                </Box>
                {/* Upsell interval */}
                <Box
                  onClick={async () => {
                    if (!isUpselled && !upsellSwitching) {
                      setPendingUpsell(true);
                      setUpsellSwitching(true);
                      try {
                        await lineItems.upsell(upsellPrimaryItem!.price_id, upsellTarget.id);
                      } catch (err: any) {
                        setPendingUpsell(null);
                        Toast.error(err?.response?.data?.error || err?.message || 'Failed');
                      } finally {
                        setUpsellSwitching(false);
                        setPendingUpsell(null);
                      }
                    }
                  }}
                  sx={capsuleBtnSx(visualIsUpselled)}>
                  <Typography component="span" sx={{ fontSize: 14, fontWeight: 700, color: 'inherit', lineHeight: 1 }}>
                    {t(INTERVAL_LOCALE_KEY[upsellInterval!] || '')}
                  </Typography>
                </Box>
              </Stack>

              {/* SAVE badge */}
              {upsellSavings > 0 && (
                <Stack
                  direction="row"
                  alignItems="center"
                  spacing={0.75}
                  sx={{
                    px: 1.5,
                    py: 0.75,
                    bgcolor: (theme) => (theme.palette.mode === 'dark' ? 'rgba(18,184,134,0.1)' : '#ebfef5'),
                    color: '#12b886',
                    fontSize: 11,
                    fontWeight: 700,
                    borderRadius: '9999px',
                    border: '1px solid',
                    borderColor: (theme) => (theme.palette.mode === 'dark' ? 'rgba(18,184,134,0.2)' : '#d3f9e8'),
                    textTransform: 'uppercase',
                    letterSpacing: '0.05em',
                  }}>
                  <TrendingDownIcon sx={{ fontSize: 14 }} />
                  <Typography
                    component="span"
                    sx={{ fontSize: 'inherit', fontWeight: 'inherit', color: 'inherit', lineHeight: 1 }}>
                    SAVE {upsellSavings}%
                  </Typography>
                </Stack>
              )}
            </Stack>
          )}
        </Box>

        {/* Billing interval toggle (multi-interval, not upsell) */}
        <BillingToggle billingInterval={billingInterval} />
      </Box>
      {/* end top section */}

      {/* ── Middle: items area — shrinks & scrolls only when content exceeds one screen ── */}
      <Box
        sx={{
          flexGrow: 0,
          flexShrink: 1,
          flexBasis: 'auto',
          minHeight: { md: 0 },
          overflowY: { md: 'auto' },
          '&::-webkit-scrollbar': { display: 'none' },
          scrollbarWidth: 'none',
        }}>
        {/* Items collapse header */}
        {showItemsCollapse && (
          <Stack
            direction="row"
            alignItems="center"
            justifyContent="space-between"
            onClick={() => setItemsExpanded(!itemsExpanded)}
            sx={{ cursor: 'pointer', mb: 1.5 }}>
            <Typography sx={{ fontSize: 14, fontWeight: 600 }}>
              {t('payment.checkout.productListTotal', { total: lineItems.items.length })}
            </Typography>
            <ExpandMoreIcon sx={{ transform: itemsExpanded ? 'rotate(180deg)' : 'rotate(0deg)', transition: '0.3s' }} />
          </Stack>
        )}

        {/* Line items — individual cards with spacing */}
        <Collapse in={itemsExpanded || !showItemsCollapse}>
          <Stack spacing={2} sx={{ mb: 2 }}>
            {lineItems.items.map((item: any) => (
              <ProductItemCard
                key={item.id}
                item={item}
                currency={currency}
                discounts={discounts}
                exchangeRate={rate.value}
                onQuantityChange={lineItems.updateQuantity}
                onUpsell={lineItems.upsell}
                onDownsell={lineItems.downsell}
                trialActive={pricing.trial.active}
                trialDays={pricing.trial.days}
                hideUpsell={hasTopUpsell || !canUpsell}
                isRateLoading={currencySwitching || (rate.hasDynamicPricing && rate.status === 'loading')}
                showFeatures={pageInfo?.showProductFeatures ?? false}
                t={t}>
                {/* Cross-sell remove button inside card */}
                {item.cross_sell && (
                  <Button
                    size="small"
                    color="error"
                    variant="text"
                    onClick={lineItems.removeCrossSell}
                    sx={{ mt: 1, ml: -0.5, textTransform: 'none', fontSize: 12 }}>
                    {t('payment.checkout.cross_sell.remove')}
                  </Button>
                )}
              </ProductItemCard>
            ))}
          </Stack>

          {/* Cross-sell card — collapses together with line items */}
          {crossSellNotAdded && (
            <Box sx={{ mb: 2 }}>
              <CrossSellCard
                crossSellItem={lineItems.crossSellItem!}
                currency={currency}
                exchangeRate={rate.value}
                crossSellRequired={lineItems.crossSellRequired}
                onAdd={lineItems.addCrossSell}
              />
            </Box>
          )}
        </Collapse>
      </Box>
      {/* end middle section */}

      {/* TrialInfo — follows items directly, no gap */}
      <Box sx={{ flexShrink: 0 }}>
        <TrialInfo
          trial={{
            active: pricing.trial.active,
            days: pricing.trial.days,
            afterTrialPrice: pricing.trial.afterTrialPrice,
            afterTrialInterval: pricing.trial.afterTrialInterval,
          }}
          mode={mode}
          items={lineItems.items}
        />
      </Box>

      {/* Spacer — fills remaining space so exchange rate is pushed to bottom */}
      <Box sx={{ flexGrow: 1, flexShrink: 1, flexBasis: 0 }} />

      {/* Exchange rate — always at the very bottom */}
      <Box sx={{ flexShrink: 0 }}>
        {/* Rate unavailable — inline hint with retry */}
        {rate.hasDynamicPricing && rate.status === 'unavailable' && !isStripe && (
          <Stack direction="row" alignItems="center" spacing={0.75} sx={{ mb: 2 }}>
            <Typography sx={{ fontSize: 13, color: 'text.secondary', fontWeight: 500 }}>
              {t('payment.dynamicPricing.unavailable.title')}
            </Typography>
            <Typography
              component="span"
              onClick={rate.refresh}
              sx={{
                fontSize: 13,
                color: 'primary.main',
                fontWeight: 600,
                cursor: 'pointer',
                '&:hover': { textDecoration: 'underline' },
              }}>
              {t('payment.dynamicPricing.unavailable.retry')}
            </Typography>
          </Stack>
        )}

        <ExchangeRateFooter
          hasDynamicPricing={rate.hasDynamicPricing}
          rate={{
            value: rate.value,
            display: rate.display,
            provider: rate.provider,
            providerDisplay: rate.providerDisplay,
            fetchedAt: rate.fetchedAt,
            status: rate.status,
          }}
          slippage={{ percent: slippage.percent, set: slippage.set }}
          currencySymbol={currency?.symbol || ''}
          isSubscription={['subscription', 'setup'].includes(mode)}
        />
      </Box>
    </Box>
  );
}
