"use client";

import { CSSProperties } from "react";
import { SatsDisplay } from "../../components/SatsDisplay";
import { components } from "../../generated/api";
import { formatDate, formatTime } from "../../utils/date";
import { formatEur } from "../../utils/exchange";
import { bannerStyles } from "../../styles/shared";
import { useTranslation } from "../../hooks/useTranslation";

type BookableSlot = components["schemas"]["BookableSlot"];
type ExchangeResponse = components["schemas"]["ExchangeResponse"];
type Direction = "buy" | "sell";
type BitcoinTransferMethod = "onchain" | "lightning";

interface BookingStepProps {
  direction: Direction;
  bitcoinTransferMethod: BitcoinTransferMethod;
  eurAmount: number;
  satsAmount: number;
  dates: Date[];
  selectedDate: Date | null;
  availableSlots: BookableSlot[];
  selectedSlot: BookableSlot | null;
  datesWithAvailability: Set<string>;
  isLoadingSlots: boolean;
  isLoadingAvailability: boolean;
  existingTradeOnSelectedDate: ExchangeResponse | null;
  userTrades: ExchangeResponse[];
  onDateSelect: (date: Date) => void;
  onSlotSelect: (slot: BookableSlot) => void;
  onBackToDetails: () => void;
}

const styles: Record<string, CSSProperties> = {
  summaryCard: {
    background: "rgba(255, 255, 255, 0.03)",
    border: "1px solid rgba(255, 255, 255, 0.08)",
    borderRadius: "12px",
    padding: "1rem 1.5rem",
    marginBottom: "1.5rem",
  },
  summaryHeader: {
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
    marginBottom: "0.5rem",
  },
  summaryTitle: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.875rem",
    color: "rgba(255, 255, 255, 0.5)",
  },
  editButton: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.75rem",
    color: "#a78bfa",
    background: "transparent",
    border: "none",
    cursor: "pointer",
    padding: 0,
  },
  summaryDetails: {
    display: "flex",
    alignItems: "center",
    gap: "0.75rem",
    flexWrap: "wrap",
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "1rem",
    color: "#fff",
  },
  summaryDirection: {
    fontWeight: 600,
  },
  summaryDivider: {
    color: "rgba(255, 255, 255, 0.3)",
  },
  summaryPaymentMethod: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.875rem",
    color: "rgba(255, 255, 255, 0.6)",
  },
  satsValue: {
    fontFamily: "'DM Mono', monospace",
    color: "#f7931a", // Bitcoin orange
  },
  section: {
    marginBottom: "2rem",
  },
  sectionTitle: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "1.1rem",
    fontWeight: 500,
    color: "#fff",
    marginBottom: "1rem",
  },
  dateGrid: {
    display: "flex",
    flexWrap: "wrap",
    gap: "0.5rem",
  },
  dateButton: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    padding: "0.75rem 1rem",
    background: "rgba(255, 255, 255, 0.03)",
    border: "1px solid rgba(255, 255, 255, 0.08)",
    borderRadius: "10px",
    cursor: "pointer",
    minWidth: "90px",
    textAlign: "center" as const,
    transition: "all 0.2s",
  },
  dateButtonSelected: {
    background: "rgba(167, 139, 250, 0.15)",
    border: "1px solid #a78bfa",
  },
  dateButtonDisabled: {
    opacity: 0.4,
    cursor: "not-allowed",
    background: "rgba(255, 255, 255, 0.01)",
    border: "1px solid rgba(255, 255, 255, 0.04)",
  },
  dateButtonHasTrade: {
    border: "1px solid rgba(251, 146, 60, 0.5)",
    background: "rgba(251, 146, 60, 0.1)",
  },
  dateWeekday: {
    color: "#fff",
    fontWeight: 500,
    fontSize: "0.875rem",
    marginBottom: "0.25rem",
  },
  dateDay: {
    color: "rgba(255, 255, 255, 0.5)",
    fontSize: "0.8rem",
  },
  dateWarning: {
    fontSize: "0.7rem",
    marginTop: "0.25rem",
    opacity: 0.8,
  },
  errorLink: {
    marginTop: "0.75rem",
    paddingTop: "0.75rem",
    borderTop: "1px solid rgba(255, 255, 255, 0.1)",
  },
  errorLinkAnchor: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    color: "#a78bfa",
    textDecoration: "none",
    fontWeight: 500,
    fontSize: "0.9rem",
  },
  slotGrid: {
    display: "flex",
    flexWrap: "wrap",
    gap: "0.5rem",
  },
  slotButton: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    padding: "0.6rem 1.25rem",
    background: "rgba(255, 255, 255, 0.03)",
    border: "1px solid rgba(255, 255, 255, 0.08)",
    borderRadius: "8px",
    color: "#fff",
    cursor: "pointer",
    fontSize: "0.9rem",
    transition: "all 0.2s",
  },
  slotButtonSelected: {
    background: "rgba(167, 139, 250, 0.15)",
    border: "1px solid #a78bfa",
  },
  emptyState: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    color: "rgba(255, 255, 255, 0.4)",
    padding: "1rem 0",
  },
};

/**
 * Check if a date has an existing trade (only consider booked trades, not cancelled ones)
 */
function getExistingTradeOnDate(
  date: Date,
  userTrades: ExchangeResponse[]
): ExchangeResponse | null {
  const dateStr = formatDate(date);
  return (
    userTrades.find((trade) => {
      const tradeDate = formatDate(new Date(trade.slot_start));
      return tradeDate === dateStr && trade.status === "booked";
    }) || null
  );
}

/**
 * Step 2 of the exchange wizard: Booking
 * Allows user to select a date and time slot for the exchange.
 */
export function BookingStep({
  direction,
  bitcoinTransferMethod,
  eurAmount,
  satsAmount,
  dates,
  selectedDate,
  availableSlots,
  selectedSlot,
  datesWithAvailability,
  isLoadingSlots,
  isLoadingAvailability,
  existingTradeOnSelectedDate,
  userTrades,
  onDateSelect,
  onSlotSelect,
  onBackToDetails,
}: BookingStepProps) {
  const t = useTranslation("exchange");
  return (
    <>
      {/* Trade Summary Card */}
      <div style={styles.summaryCard}>
        <div style={styles.summaryHeader}>
          <span style={styles.summaryTitle}>{t("bookingStep.yourExchange")}</span>
          <button onClick={onBackToDetails} style={styles.editButton}>
            {t("bookingStep.edit")}
          </button>
        </div>
        <div style={styles.summaryDetails}>
          <span
            style={{
              ...styles.summaryDirection,
              color: direction === "buy" ? "#4ade80" : "#f87171",
            }}
          >
            {direction === "buy" ? t("bookingStep.buy") : t("bookingStep.sell")} BTC
          </span>
          <span style={styles.summaryDivider}>•</span>
          <span>{formatEur(eurAmount)}</span>
          <span style={styles.summaryDivider}>↔</span>
          <span style={styles.satsValue}>
            <SatsDisplay sats={satsAmount} />
          </span>
          <span style={styles.summaryDivider}>•</span>
          <span style={styles.summaryPaymentMethod}>
            {direction === "buy" ? t("bookingStep.receiveVia") : t("bookingStep.sendVia")}{" "}
            {bitcoinTransferMethod === "onchain"
              ? t("transferMethod.onchain")
              : t("transferMethod.lightning")}
          </span>
        </div>
      </div>

      {/* Date Selection */}
      <div style={styles.section}>
        <h2 style={styles.sectionTitle}>{t("bookingStep.selectDate")}</h2>
        <div style={styles.dateGrid}>
          {dates.map((date) => {
            const dateStr = formatDate(date);
            const isSelected = selectedDate && formatDate(selectedDate) === dateStr;
            const hasAvailability = datesWithAvailability.has(dateStr);
            const isDisabled = !hasAvailability || isLoadingAvailability;
            const hasExistingTrade = getExistingTradeOnDate(date, userTrades) !== null;

            return (
              <button
                key={dateStr}
                data-testid={`date-${dateStr}`}
                onClick={() => onDateSelect(date)}
                disabled={isDisabled}
                style={{
                  ...styles.dateButton,
                  ...(isSelected ? styles.dateButtonSelected : {}),
                  ...(isDisabled ? styles.dateButtonDisabled : {}),
                  ...(hasExistingTrade && !isDisabled ? styles.dateButtonHasTrade : {}),
                }}
              >
                <div style={styles.dateWeekday}>
                  {date.toLocaleDateString("en-US", { weekday: "short" })}
                </div>
                <div style={styles.dateDay}>
                  {date.toLocaleDateString("en-US", {
                    month: "short",
                    day: "numeric",
                  })}
                </div>
                {hasExistingTrade && !isDisabled && <div style={styles.dateWarning}>⚠️</div>}
              </button>
            );
          })}
        </div>
      </div>

      {/* Warning for existing trade on selected date */}
      {existingTradeOnSelectedDate && (
        <div style={bannerStyles.errorBanner}>
          <div>{t("bookingStep.existingTradeWarning")}</div>
          <div style={styles.errorLink}>
            <a
              href={`/trades/${existingTradeOnSelectedDate.public_id}`}
              style={styles.errorLinkAnchor}
            >
              {t("bookingStep.viewExistingTrade")}
            </a>
          </div>
        </div>
      )}

      {/* Available Slots */}
      {selectedDate && !existingTradeOnSelectedDate && (
        <div style={styles.section}>
          <h2 style={styles.sectionTitle}>
            {t("bookingStep.availableSlots")}{" "}
            {selectedDate.toLocaleDateString("en-US", {
              weekday: "long",
              month: "long",
              day: "numeric",
            })}
          </h2>

          {isLoadingSlots ? (
            <div style={styles.emptyState}>{t("bookingStep.loadingSlots")}</div>
          ) : availableSlots.length === 0 ? (
            <div style={styles.emptyState}>{t("bookingStep.noSlots")}</div>
          ) : (
            <div style={styles.slotGrid}>
              {availableSlots.map((slot) => {
                const isSelected = selectedSlot?.start_time === slot.start_time;
                return (
                  <button
                    key={slot.start_time}
                    onClick={() => onSlotSelect(slot)}
                    style={{
                      ...styles.slotButton,
                      ...(isSelected ? styles.slotButtonSelected : {}),
                    }}
                  >
                    {formatTime(slot.start_time)}
                  </button>
                );
              })}
            </div>
          )}
        </div>
      )}
    </>
  );
}
