"use client";

import { Connector } from "@/types/connector/connector";
import { useState, useEffect, useRef } from "react";
import { useChargePoint } from "../../detail/hooks/useChargePoint";
import { useRouter } from "next/navigation";
import ConnectorCard from "../components/ConnectorCard";
import ConnectorModal from "../modals/ConnectorModal";
import RefreshButton from "../components/RefreshButton";
import {
  amountWithTax,
  formatCurrency,
  getDynamicFlatFeePricing,
  getPriceComponentsArray,
} from "../helper";
import { AlertTriangle, Clock3, WalletCards } from "lucide-react";
// Rates are rendered inside ConnectorDetails for desktop; modal shows rates at bottom.

interface ConnectorSelectorProps {
  connectors: Connector[];
  stationId: string;
  onRefresh?: () => void;
}

type StartFeeComponent = {
  type: string;
  price: number;
  tax: number;
};

type SessionFeeDialog = {
  mode: "confirm" | "blocked";
  connectorName: string;
  currency: string;
  walletBalance: number;
  flatFee: number;
  minimumWallet: number;
  requiredBalance: number;
  remainingChargingBudget: number;
  flatFeePricing: ReturnType<typeof getDynamicFlatFeePricing> | null;
};

const SessionFeeReviewDialog = ({
  dialog,
  onCancel,
  onConfirm,
}: {
  dialog: SessionFeeDialog;
  onCancel: () => void;
  onConfirm: () => void;
}) => {
  const isBlocked = dialog.mode === "blocked";
  const hasFlatFee = dialog.flatFee > 0;
  const remainingBudget = Math.max(0, dialog.remainingChargingBudget);

  return (
    <div className="fixed inset-0 z-[60] flex items-end justify-center bg-black/40 px-4 py-5 backdrop-blur-sm sm:items-center">
      <div className="w-full max-w-md overflow-hidden rounded-2xl bg-white shadow-2xl dark:bg-gray-900">
        <div className="border-b border-gray-100 px-5 py-4 dark:border-gray-800">
          <div className="flex items-start gap-3">
            <div
              className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl ${
                isBlocked
                  ? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-300"
                  : "bg-brand-100 text-brand-700 dark:bg-brand-900/30 dark:text-brand-200"
              }`}
            >
              {isBlocked ? (
                <AlertTriangle className="h-5 w-5" />
              ) : (
                <WalletCards className="h-5 w-5" />
              )}
            </div>
            <div>
              <h3 className="text-lg font-semibold text-gray-950 dark:text-white">
                {isBlocked ? "Wallet balance is too low" : "Confirm Charging"}
              </h3>
              <p className="mt-1 text-sm leading-5 text-gray-600 dark:text-gray-300">
                {isBlocked
                  ? `${dialog.connectorName} requires the session reserve before charging can start.`
                  : "Review your wallet before charging"}
              </p>
            </div>
          </div>
        </div>

        <div className="space-y-4 px-5 py-4">
          {hasFlatFee ? (
            <div className="space-y-3 rounded-xl bg-gray-50 p-4 text-sm dark:bg-gray-800">
              <div className="flex items-center justify-between gap-3">
                <span className="text-gray-600 dark:text-gray-300">Current wallet</span>
                <span className="font-semibold text-gray-950 dark:text-white">
                  {formatCurrency(dialog.walletBalance, dialog.currency)}
                </span>
              </div>
              <div className="flex items-center justify-between gap-3">
                <span className="text-gray-600 dark:text-gray-300">Service fee</span>
                <span className="text-right font-semibold text-gray-950 dark:text-white">
                  See pricing details below
                </span>
              </div>
            </div>
          ) : (
            <div className="grid grid-cols-2 gap-2">
              <div className="rounded-xl bg-gray-50 p-3 dark:bg-gray-800">
                <div className="text-[11px] font-medium uppercase text-gray-500 dark:text-gray-400">
                  Wallet
                </div>
                <div className="mt-1 text-sm font-semibold text-gray-950 dark:text-white">
                  {formatCurrency(dialog.walletBalance, dialog.currency)}
                </div>
              </div>
              <div className="rounded-xl bg-gray-50 p-3 dark:bg-gray-800">
                <div className="text-[11px] font-medium uppercase text-gray-500 dark:text-gray-400">
                  Reserved
                </div>
                <div className="mt-1 text-sm font-semibold text-gray-950 dark:text-white">
                  {formatCurrency(dialog.requiredBalance, dialog.currency)}
                </div>
              </div>
              <div
                className={`rounded-xl p-3 ${
                  isBlocked ? "bg-red-50 dark:bg-red-900/20" : "bg-brand-50 dark:bg-brand-900/20"
                }`}
              >
                <div className="text-[11px] font-medium uppercase text-gray-500 dark:text-gray-400">
                  Available after reserve
                </div>
                <div
                  className={`mt-1 text-sm font-semibold ${
                    isBlocked
                      ? "text-red-700 dark:text-red-300"
                      : "text-brand-700 dark:text-brand-200"
                  }`}
                >
                  {formatCurrency(remainingBudget, dialog.currency)}
                </div>
              </div>
            </div>
          )}

          {hasFlatFee && (
            <div>
              <div className="text-sm font-semibold text-gray-900 dark:text-gray-100">
                Service fee by charging duration
              </div>
              {dialog.flatFeePricing && (
                <div className="mt-3 flex items-center gap-3 rounded-xl border border-brand-200 bg-brand-50 px-3 py-3 dark:border-brand-800 dark:bg-brand-900/20">
                  <Clock3 className="h-5 w-5 shrink-0 text-brand-600 dark:text-brand-300" />
                  <p className="text-sm font-semibold leading-5 text-gray-800 dark:text-gray-100">
                    {dialog.flatFeePricing.description}
                  </p>
                </div>
              )}
            </div>
          )}

          {!hasFlatFee && (
            <div className="space-y-2 rounded-xl border border-gray-100 p-3 text-sm dark:border-gray-800">
              <div className="flex justify-between gap-3">
                <span className="text-gray-600 dark:text-gray-300">Minimum wallet reserve</span>
                <span className="font-semibold text-gray-950 dark:text-white">
                  {formatCurrency(dialog.minimumWallet, dialog.currency)}
                </span>
              </div>
            </div>
          )}
        </div>

        <div className="flex gap-3 border-t border-gray-100 px-5 py-4 dark:border-gray-800">
          {!isBlocked && (
            <button
              type="button"
              onClick={onCancel}
              className="flex-1 rounded-xl border border-gray-200 px-4 py-3 text-sm font-semibold text-gray-700 transition-colors hover:bg-gray-50 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-800"
            >
              Cancel
            </button>
          )}
          <button
            type="button"
            onClick={isBlocked ? onCancel : onConfirm}
            className={`flex-1 rounded-xl px-4 py-3 text-sm font-semibold text-white transition-colors ${
              isBlocked
                ? "bg-red-600 hover:bg-red-700"
                : "bg-brand-600 hover:bg-brand-700 active:bg-brand-800"
            }`}
          >
            {isBlocked ? "Got it" : "Confirm & Start Charging"}
          </button>
        </div>
      </div>
    </div>
  );
};

const ConnectorSelector = ({ connectors, stationId, onRefresh }: ConnectorSelectorProps) => {
  const [selectedConnector, setSelectedConnector] = useState<string | null>(null);
  const [expandedConnector, setExpandedConnector] = useState<string | null>(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [modalConnector, setModalConnector] = useState<Connector | null>(null);
  const [isMobile, setIsMobile] = useState(false);
  const [sessionFeeDialog, setSessionFeeDialog] = useState<SessionFeeDialog | null>(null);
  const sessionFeeDialogResolver = useRef<((confirmed: boolean) => void) | null>(null);
  const { chargePoint: currentChargePoint, startSession, isStarting } = useChargePoint(stationId);
  const router = useRouter();
  const liveConnectors = (currentChargePoint?.connectors ?? connectors) as Connector[];

  // Check if screen is mobile size
  useEffect(() => {
    const checkMobile = () => {
      setIsMobile(window.innerWidth < 768);
    };

    checkMobile();
    window.addEventListener("resize", checkMobile);
    return () => window.removeEventListener("resize", checkMobile);
  }, []);

  // Prevent body scroll when modal is open
  useEffect(() => {
    if (isModalOpen) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "unset";
    }

    return () => {
      document.body.style.overflow = "unset";
    };
  }, [isModalOpen]);

  const openConnectorModal = (connector: Connector) => {
    if (isMobile) {
      setModalConnector(connector);
      setIsModalOpen(true);
    } else {
      toggleConnectorDetails(connector.id!);
    }
  };

  const closeModal = () => {
    setIsModalOpen(false);
    setModalConnector(null);
    // When closing modal, unselect the connector
    setSelectedConnector(null);
  };

  const isConnectorSelectable = (connector: Connector) =>
    (currentChargePoint?.online || false) &&
    !["Finishing", "Charging", "SuspendedEV", "SuspendedEVSE"].includes(connector.status as any);

  const fetchWalletBalance = async () => {
    const response = await fetch("/api/wallet/balance", {
      method: "GET",
      headers: { "Content-Type": "application/json" },
      cache: "no-store",
    });
    const data = await response.json().catch(() => null);
    if (!response.ok || data?.ok === false) {
      throw new Error(data?.message || "Unable to verify wallet balance");
    }
    const payload = data?.result ?? data;
    const rawBalance = payload?.balance ?? payload?.wallet?.balance;
    const balance = typeof rawBalance === "number" ? rawBalance : Number(rawBalance);
    if (!Number.isFinite(balance)) {
      throw new Error("Unable to verify wallet balance");
    }
    return {
      balance,
      currency: payload?.currency ?? payload?.wallet?.currency,
    };
  };

  const requestSessionFeeDecision = (dialog: SessionFeeDialog) =>
    new Promise<boolean>((resolve) => {
      sessionFeeDialogResolver.current = resolve;
      setSessionFeeDialog(dialog);
    });

  const closeSessionFeeDialog = (confirmed: boolean) => {
    const resolver = sessionFeeDialogResolver.current;
    sessionFeeDialogResolver.current = null;
    setSessionFeeDialog(null);
    resolver?.(confirmed);
  };

  const validateWalletForConnector = async (connector: Connector) => {
    const rate = connector.rate;
    if (!rate) return;

    const currency = rate.currency || "IDR";
    const components = getPriceComponentsArray(rate) as StartFeeComponent[];
    const flatFee = components
      .filter((component) => component.type === "FLAT")
      .reduce(
        (total, component) => total + amountWithTax(component.price || 0, component.tax || 0),
        0,
      );
    const minimumWallet = Number(rate.minimum_amount || 0);

    if (flatFee <= 0 && minimumWallet <= 0) return;

    const wallet = await fetchWalletBalance();
    const walletCurrency = wallet.currency || currency;
    const requiredBalance = flatFee + minimumWallet;
    const remainingChargingBudget = wallet.balance - requiredBalance;

    if (wallet.balance < requiredBalance) {
      await requestSessionFeeDecision({
        mode: "blocked",
        connectorName: connector.name || `Connector ${connector.connector_number}`,
        currency: walletCurrency,
        walletBalance: wallet.balance,
        flatFee,
        minimumWallet,
        requiredBalance,
        remainingChargingBudget,
        flatFeePricing: flatFee > 0 ? getDynamicFlatFeePricing(flatFee, walletCurrency) : null,
      });
      throw new Error("Insufficient wallet balance");
    }

    if (flatFee > 0) {
      const shouldContinue = await requestSessionFeeDecision({
        mode: "confirm",
        connectorName: connector.name || `Connector ${connector.connector_number}`,
        currency: walletCurrency,
        walletBalance: wallet.balance,
        flatFee,
        minimumWallet,
        requiredBalance,
        remainingChargingBudget,
        flatFeePricing: getDynamicFlatFeePricing(flatFee, walletCurrency),
      });
      if (!shouldContinue) {
        throw new Error("Session start cancelled");
      }
    }
  };

  const toggleConnectorDetails = (connectorId: string) => {
    if (expandedConnector === connectorId) {
      // If selected, do not collapse
      if (selectedConnector === connectorId) return;
      setExpandedConnector(null);
      return;
    }
    // Expanding
    setExpandedConnector(connectorId);
  };

  const handleStartSession = async (connectorId: string) => {
    try {
      const connector = liveConnectors.find((item) => item.id === connectorId);
      if (connector) {
        await validateWalletForConnector(connector);
      }
      const session = await startSession(connectorId);
      if (!session._id) {
        throw new Error('Start session response did not include a session ID');
      }
      router.push(`/sessions/${encodeURIComponent(session._id)}`);
      onRefresh?.();
    } catch (e) {
      console.error("Failed to start session:", e);
      throw e;
    }
  };

  return (
    <>
      <div className="relative">
        {/* Header with Refresh Button */}
        <div className="flex items-center justify-between mb-6">
          <h2 className="text-xl md:text-2xl font-semibold text-black dark:text-white">
            Available Connectors
          </h2>
          {onRefresh && <RefreshButton onRefresh={onRefresh} />}
        </div>

        <div className="space-y-3 md:space-y-4">
          {liveConnectors.map((connector) => (
            <ConnectorCard
              key={connector.id}
              connector={connector}
              selectedConnector={selectedConnector}
              expandedConnector={expandedConnector}
              isMobile={isMobile}
              online={currentChargePoint?.online || false}
              onCardClick={openConnectorModal}
              onToggleDetails={toggleConnectorDetails}
              onSelectConnector={(id) => {
                setSelectedConnector(id);
                if (id) {
                  setExpandedConnector(id);
                }
              }}
              isConnectorSelectable={isConnectorSelectable}
              connectors={liveConnectors}
              isStarting={isStarting}
              onStartSession={handleStartSession}
            />
          ))}
        </div>

        {/* Desktop: ConnectButton and rates are shown inside the expanded card */}
      </div>

      {/* Mobile Modal */}
      {isMobile && isModalOpen && modalConnector && (
        <ConnectorModal
          connector={modalConnector}
          selectedConnector={selectedConnector}
          isStarting={isStarting}
          online={currentChargePoint?.online || false}
          connectors={liveConnectors}
          onClose={closeModal}
          onSelectConnector={setSelectedConnector}
          onStartSession={handleStartSession}
          isConnectorSelectable={isConnectorSelectable}
        />
      )}

      {sessionFeeDialog && (
        <SessionFeeReviewDialog
          dialog={sessionFeeDialog}
          onCancel={() => closeSessionFeeDialog(false)}
          onConfirm={() => closeSessionFeeDialog(true)}
        />
      )}
    </>
  );
};

export default ConnectorSelector;
