import { useState } from 'react';
import { Linking, Pressable, Text, View } from 'react-native';
import { ExternalLink } from 'lucide-react-native';
import { toast } from 'sonner-native';
import type { BillingCadence, BillingStatus } from '@/api/types';
import {
  useCreateCheckoutSession,
  useCreatePortalSession,
  useNetworkBilling,
  useNetworkUsage,
} from '@/hooks/use-billing';
import { useIsNetworkAdmin } from '@/hooks/use-networks';
import { toUserMessage } from '@/lib/errors';
import { cn } from '@/lib/utils';

function formatCents(cents: number): string {
  if (cents % 100 === 0) return `$${cents / 100}`;
  return `$${(cents / 100).toFixed(2)}`;
}

function formatDate(date: Date): string {
  return date.toLocaleDateString(undefined, {
    month: 'long',
    day: 'numeric',
    year: 'numeric',
  });
}

function InfoRow({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <View className="flex-row items-center gap-3 px-1 py-2">
      <Text className="text-muted-foreground text-sm">{label}</Text>
      <View className="flex-1" />
      <View>{value}</View>
    </View>
  );
}

/**
 * Plan + usage summary for every member, plus admin-only upgrade/manage
 * controls. Mirrors desktop's BillingSection — `/usage` powers the
 * everyone-visible summary; `/billing` (admin-gated) drives the controls.
 * Stripe checkout/portal URLs are opened in the system browser.
 */
export function BillingSection({ networkId }: { networkId: string }) {
  const isAdmin = useIsNetworkAdmin(networkId);
  const { data: usage } = useNetworkUsage(networkId);

  const isPro = usage?.plan === 'pro';

  return (
    <View className="px-3">
      <Text className="text-foreground text-base font-semibold pt-2 pb-2">
        Plan &amp; billing
      </Text>

      <InfoRow
        label="Plan"
        value={
          <Text className="text-foreground text-sm font-medium">
            {isPro ? 'Llink Pro' : 'Llink Free'}
          </Text>
        }
      />
      {!isPro && usage?.limit != null ? (
        <InfoRow
          label="Today’s messages"
          value={
            <Text className="text-foreground text-sm tabular-nums">
              {usage.used} / {usage.limit}
            </Text>
          }
        />
      ) : null}

      {isAdmin ? <AdminBillingControls networkId={networkId} /> : null}
    </View>
  );
}

function AdminBillingControls({ networkId }: { networkId: string }) {
  const {
    data: billing,
    isLoading,
    error,
  } = useNetworkBilling(networkId, true);

  if (isLoading || !billing) {
    return (
      <Text className="text-muted-foreground text-sm px-1 py-2">
        {error ? `Couldn’t load billing: ${toUserMessage(error)}` : 'Loading…'}
      </Text>
    );
  }

  return billing.plan === 'pro' ? (
    <ProBilling networkId={networkId} billing={billing} />
  ) : (
    <FreeBilling networkId={networkId} billing={billing} />
  );
}

function FreeBilling({
  networkId,
  billing,
}: {
  networkId: string;
  billing: BillingStatus;
}) {
  const createCheckout = useCreateCheckoutSession(networkId);
  const [cadence, setCadence] = useState<BillingCadence>('annual');

  const annualPerSeatMonthlyCents = Math.round(billing.price_annual_cents / 12);
  const savingsPct = Math.round(
    (1 - annualPerSeatMonthlyCents / billing.price_monthly_cents) * 100,
  );

  const handleUpgrade = async () => {
    try {
      const { url } = await createCheckout.mutateAsync(cadence);
      await Linking.openURL(url);
    } catch (err) {
      toast.error(toUserMessage(err));
    }
  };

  return (
    <View className="mt-2 gap-2">
      <CadenceOption
        label="Annual"
        note="Billed annually"
        perSeatCents={annualPerSeatMonthlyCents}
        badge={savingsPct > 0 ? `Save ${savingsPct}%` : undefined}
        selected={cadence === 'annual'}
        onPress={() => setCadence('annual')}
      />
      <CadenceOption
        label="Monthly"
        note="Billed monthly · cancel anytime"
        perSeatCents={billing.price_monthly_cents}
        selected={cadence === 'monthly'}
        onPress={() => setCadence('monthly')}
      />
      <Pressable
        onPress={handleUpgrade}
        disabled={createCheckout.isPending}
        className="mt-2 rounded-xl bg-primary py-3 items-center"
      >
        <Text className="text-primary-foreground text-base font-semibold">
          {createCheckout.isPending ? 'Opening Stripe…' : 'Upgrade to Pro'}
        </Text>
      </Pressable>
    </View>
  );
}

function CadenceOption({
  label,
  note,
  perSeatCents,
  badge,
  selected,
  onPress,
}: {
  label: string;
  note: string;
  perSeatCents: number;
  badge?: string;
  selected: boolean;
  onPress: () => void;
}) {
  return (
    <Pressable
      onPress={onPress}
      className={cn(
        'flex-row items-center gap-3 rounded-xl border px-4 py-3',
        selected ? 'border-primary bg-accent' : 'border-border',
      )}
    >
      <View
        className={cn(
          'h-5 w-5 rounded-full border-2',
          selected ? 'border-primary bg-primary' : 'border-muted-foreground',
        )}
      />
      <View className="flex-1">
        <View className="flex-row items-center gap-2">
          <Text className="text-foreground text-sm font-medium">{label}</Text>
          {badge ? (
            <View className="bg-primary rounded-full px-2 py-0.5">
              <Text className="text-primary-foreground text-[10px] font-semibold">
                {badge}
              </Text>
            </View>
          ) : null}
        </View>
        <Text className="text-muted-foreground text-xs">{note}</Text>
      </View>
      <View className="items-end">
        <Text className="text-foreground text-sm font-medium">
          {formatCents(perSeatCents)}
        </Text>
        <Text className="text-muted-foreground text-xs">per seat / mo</Text>
      </View>
    </Pressable>
  );
}

function ProBilling({
  networkId,
  billing,
}: {
  networkId: string;
  billing: BillingStatus;
}) {
  const createPortal = useCreatePortalSession(networkId);

  const cadenceLabel = billing.cadence === 'annual' ? 'Annual' : 'Monthly';
  const perSeatCents =
    billing.cadence === 'annual'
      ? Math.round(billing.price_annual_cents / 12)
      : billing.price_monthly_cents;
  const renewal = billing.current_period_end
    ? formatDate(billing.current_period_end)
    : null;

  const handleManage = async () => {
    try {
      const { url } = await createPortal.mutateAsync();
      await Linking.openURL(url);
    } catch (err) {
      toast.error(toUserMessage(err));
    }
  };

  return (
    <View className="mt-2">
      {billing.cancel_at_period_end && renewal ? (
        <Text className="text-destructive text-sm py-2">
          Your subscription downgrades to Free on {renewal}.
        </Text>
      ) : null}
      {billing.plan_status === 'past_due' ? (
        <Text className="text-destructive text-sm py-2">
          Your last payment failed. Update your payment method to keep Pro
          active.
        </Text>
      ) : null}

      <InfoRow
        label="Billing"
        value={
          <Text className="text-foreground text-sm">
            {`${cadenceLabel} · ${formatCents(perSeatCents)} / seat / mo`}
          </Text>
        }
      />
      <InfoRow
        label="Seats"
        value={<Text className="text-foreground text-sm">{billing.seats}</Text>}
      />
      {renewal ? (
        <InfoRow
          label={billing.cancel_at_period_end ? 'Ends' : 'Renews'}
          value={<Text className="text-foreground text-sm">{renewal}</Text>}
        />
      ) : null}

      <Pressable
        onPress={handleManage}
        disabled={createPortal.isPending}
        className="mt-2 flex-row items-center justify-center gap-2 rounded-xl border border-border py-3"
      >
        <ExternalLink color="#fafafa" size={15} />
        <Text className="text-foreground text-base font-medium">
          {createPortal.isPending ? 'Opening Stripe…' : 'Manage subscription'}
        </Text>
      </Pressable>
    </View>
  );
}
