import { Box, Button, Group, Image, Modal, Stack, Text } from "@mantine/core";
import { Check, ShieldCheck } from "lucide-react";
import { useEffect, useMemo, useState } from "react";

import type { PaymentMethod } from "@/services/payments.service";

interface ProviderOption {
  method: PaymentMethod;
  label: string;
  description: string;
  logo: string;
  /** Currencies this provider settles in. */
  currencies: string[];
  accent: string;
}

// Only Telebirr and Waafi are enabled for now.
const PROVIDERS: ProviderOption[] = [
  {
    method: "TELEBIRR",
    label: "telebirr",
    description: "Ethiopian mobile money · ETB",
    logo: "/assets/telebirr.jpeg",
    currencies: ["ETB"],
    accent: "#0A6F4D",
  },
  {
    method: "WAAFI",
    label: "Waafi",
    description: "Djibouti mobile money · USD",
    logo: "/assets/waafi.jpeg",
    currencies: ["USD"],
    accent: "#2E5B96",
  },
];

/**
 * Pick the provider that settles in the booking's currency. USD → Waafi,
 * ETB → Telebirr. Falls back to the first provider when unknown.
 */
function providersForCurrency(currency?: string | null): ProviderOption[] {
  const cur = currency?.trim().toUpperCase();
  if (!cur) return PROVIDERS;
  const matched = PROVIDERS.filter((p) => p.currencies.includes(cur));
  return matched.length > 0 ? matched : PROVIDERS;
}

function ProviderRow({
  option,
  selected,
  onSelect,
}: {
  option: ProviderOption;
  selected: boolean;
  onSelect: () => void;
}) {
  return (
    <Group
      onClick={onSelect}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          onSelect();
        }
      }}
      gap={14}
      wrap="nowrap"
      align="center"
      style={{
        cursor: "pointer",
        borderRadius: 14,
        padding: "14px 16px",
        border: `1.5px solid ${selected ? option.accent : "#E6ECF1"}`,
        backgroundColor: selected ? "#F6FBF8" : "#fff",
        boxShadow: selected
          ? `0 0 0 1px ${option.accent}, 0 6px 18px rgba(16,24,40,0.06)`
          : "none",
        transition: "border-color .14s, box-shadow .14s, background-color .14s",
      }}
    >
      <Box
        style={{
          width: 52,
          height: 52,
          flexShrink: 0,
          borderRadius: 12,
          overflow: "hidden",
          border: "1px solid #EEF2F6",
          backgroundColor: "#fff",
        }}
      >
        <Image
          src={option.logo}
          alt={`${option.label} logo`}
          w={52}
          h={52}
          fit="cover"
        />
      </Box>
      <Box style={{ flex: 1, minWidth: 0 }}>
        <Text fz="15px" fw={800} c="#10202F" tt="capitalize">
          {option.label}
        </Text>
        <Text fz="12.5px" c="#7A8794" truncate>
          {option.description}
        </Text>
      </Box>
      <Box
        style={{
          width: 22,
          height: 22,
          flexShrink: 0,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          borderRadius: "50%",
          border: `2px solid ${selected ? option.accent : "#CBD5E1"}`,
          backgroundColor: selected ? option.accent : "transparent",
          transition: "all .14s",
        }}
      >
        {selected && <Check size={13} color="#fff" strokeWidth={3} />}
      </Box>
    </Group>
  );
}

export function PaymentMethodModal({
  opened,
  onClose,
  amountLabel,
  currency,
  onConfirm,
  processing,
  error,
}: {
  opened: boolean;
  onClose: () => void;
  /** Human-readable total, e.g. "ETB 12,500". */
  amountLabel?: string;
  /** Booking payment currency — drives which provider is shown (USD → Waafi, ETB → Telebirr). */
  currency?: string | null;
  onConfirm: (method: PaymentMethod) => void;
  processing?: boolean;
  error?: string | null;
}) {
  const providers = useMemo(() => providersForCurrency(currency), [currency]);
  const [method, setMethod] = useState<PaymentMethod>(providers[0].method);

  // Keep the selection valid when the currency (and therefore provider list) changes.
  useEffect(() => {
    if (!providers.some((p) => p.method === method)) {
      setMethod(providers[0].method);
    }
  }, [providers, method]);

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      centered
      radius={18}
      size={480}
      padding={0}
      withCloseButton={false}
      overlayProps={{ backgroundOpacity: 0.45, blur: 3 }}
    >
      {/* Header */}
      <Box px={24} pt={24} pb={18}>
        <Text fw={800} fz="19px" c="#10202F" lh={1.2}>
          Complete your payment
        </Text>
        <Text mt={4} fz="13px" c="#7A8794">
          Choose how you'd like to pay for this booking.
        </Text>

        {amountLabel && (
          <Group
            mt={16}
            justify="space-between"
            align="center"
            px={16}
            py={13}
            style={{
              borderRadius: 12,
              background:
                "linear-gradient(135deg, #FEF8EC 0%, #F4FAF7 100%)",
              border: "1px solid #F2E4C4",
            }}
          >
            <Text fz="12.5px" fw={700} c="#B07D14" tt="uppercase" style={{ letterSpacing: 0.5 }}>
              Amount due
            </Text>
            <Text fz="20px" fw={800} c="#10202F">
              {amountLabel}
            </Text>
          </Group>
        )}
      </Box>

      {/* Provider options */}
      <Box px={24} pb={4}>
        <Text fz="11.5px" fw={700} c="#9AA8B5" tt="uppercase" mb={10} style={{ letterSpacing: 0.6 }}>
          Payment method
        </Text>
        <Stack gap={10}>
          {providers.map((option) => (
            <ProviderRow
              key={option.method}
              option={option}
              selected={method === option.method}
              onSelect={() => setMethod(option.method)}
            />
          ))}
        </Stack>
      </Box>

      {/* Footer */}
      <Box px={24} pt={16} pb={22}>
        {error && (
          <Text fz="12.5px" c="#C0392B" fw={600} mb={10}>
            {error}
          </Text>
        )}

        <Group gap={6} align="center" justify="center" mb={12}>
          <ShieldCheck size={14} color="#0A8A5F" />
          <Text fz="11.5px" c="#7A8794">
            Secured · you'll be redirected to your provider to pay
          </Text>
        </Group>

        <Group gap={10} wrap="nowrap">
          <Button
            variant="default"
            radius={12}
            onClick={onClose}
            disabled={processing}
            styles={{
              root: { height: 48, flex: "0 0 38%" },
              label: { fontSize: 14, fontWeight: 700, color: "#475569" },
            }}
          >
            Cancel
          </Button>
          <Button
            radius={12}
            color="edr-green"
            disabled={processing}
            loading={processing}
            onClick={() => onConfirm(method)}
            styles={{
              root: { height: 48, flex: 1 },
              label: { fontSize: 14, fontWeight: 800 },
            }}
          >
            {processing ? "Redirecting…" : "Continue to payment"}
          </Button>
        </Group>
      </Box>
    </Modal>
  );
}
