"use client";

import { CostBreakdown, Session } from "@/types/session/session";
import { useState } from "react";
import { formatDateTime, formatCurrency } from "@/lib/utils.client";
import { ChevronUp, ChevronDown, Clock } from "lucide-react";
import { useSession } from "@/modules/sessionModule/detail/hooks/useSession";
import {
  formatBreakdownType,
  hasTaxBreakdown,
  formatTaxLabel,
  resolveBreakdownLabel,
} from "@/modules/sessionModule/detail/utils/costBreakdown";
import {
  getDynamicFlatFeePricing,
  toPerMinuteRateDisplay,
} from "@/modules/chargepointModule/connectorModule/helper";
import { projectLiveIdleCost } from "@/modules/sessionModule/detail/utils/liveIdleCost";
import { isACPowerType } from "@/modules/sessionModule/detail/utils/powerType";
import { isSessionIdleOngoing } from "@/modules/sessionModule/detail/sessionDetailUtils";
import {
  formatBatteryPercentage,
  shouldShowCompletedSessionDetails,
} from "@/modules/sessionModule/detail/sessionPresentation";

interface ChargingMetricsProps {
  readonly initialSession: Session;
}

const formatBreakdownCurrency = (amount: number, currency?: string | null) => {
  try {
    return new Intl.NumberFormat("id-ID", {
      style: "currency",
      currency: currency || "IDR",
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    }).format(amount);
  } catch {
    return formatCurrency(amount);
  }
};

const formatBreakdownQuantity = (value: number) => {
  if (!Number.isFinite(value)) return "0";
  return new Intl.NumberFormat("id-ID", {
    minimumFractionDigits: value % 1 === 0 ? 0 : 2,
    maximumFractionDigits: 2,
  }).format(value);
};

const formatSessionTimestamp = (value?: string | null) => {
  return value ? formatDateTime(value) : "Not available";
};

const getBreakdownUnitLabel = (item: CostBreakdown) => {
  if (item.unit) return item.unit;
  if (item.type === "ENERGY") return "kWh";
  if (item.type === "TIME" || item.type === "IDLE") return "hour";
  if (item.type === "FLAT") return "session";
  return "unit";
};

const isFlatFee = (item: CostBreakdown) => String(item.type || "").toUpperCase() === "FLAT";

const ChargingMetrics = ({ initialSession }: ChargingMetricsProps) => {
  const [showEnergyDetails, setShowEnergyDetails] = useState(false);
  const [showCostDetails, setShowCostDetails] = useState(false);
  const {
    session: liveSession,
    idleCostEstimate,
    isValidating,
  } = useSession(initialSession._id, initialSession);
  const data = liveSession ?? initialSession;
  const displayCost = projectLiveIdleCost(
    data.cost,
    isSessionIdleOngoing(data) ? idleCostEstimate : null,
    data.fee_details,
  );

  const updatedAt: string | null =
    (data.updated_at as string) || (data.energy_report?.timestamp as string | undefined) || null;

  const timeAgo = (dateString: string): string => {
    const date = new Date(dateString);
    const diffMs = Date.now() - date.getTime();
    if (isNaN(diffMs)) return "";
    const sec = Math.floor(diffMs / 1000);
    if (sec < 10) return "just now";
    if (sec < 60) return `${sec}s ago`;
    const min = Math.floor(sec / 60);
    if (min < 60) return `${min}m ago`;
    const hrs = Math.floor(min / 60);
    if (hrs < 24) return `${hrs}h ago`;
    const days = Math.floor(hrs / 24);
    return `${days}d ago`;
  };

  const powerUsed = (data.metrics?.energy_consumed || 0) / 1000;
  const totalCost = displayCost?.amount || 0;

  const stateOfCharge = data.energy_report?.state_of_charge?.value;
  const isACSession = isACPowerType(data.power_type);
  const showCompletedDetails = shouldShowCompletedSessionDetails(data.status);
  const chargingStart = data.metrics?.charging_start;
  const chargingStop = data.metrics?.charging_stop;
  const chargingStopReason = data.metrics?.charging_stop_reason?.trim();
  const hasChargingDetails = Boolean(chargingStart || chargingStop || chargingStopReason);

  return (
    <div className="w-full max-w-6xl mx-auto mt-8 p-6 bg-white rounded-xl shadow-md space-y-6 dark:bg-gray-800 dark:border-gray-700 relative">
      {updatedAt && (
        <div className="flex w-full justify-end items-center gap-2 text-xs text-gray-500 dark:text-gray-400 mb-2">
          <Clock className={`w-4 h-4 ${isValidating ? "animate-pulse" : ""}`} />
          <span>Last updated:</span>
          <span className="text-gray-700 dark:text-gray-300">{formatDateTime(updatedAt)}</span>
          <span className="text-gray-400">({timeAgo(updatedAt)})</span>
          {isValidating && (
            <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">
              <span className="w-1.5 h-1.5 rounded-full bg-emerald-600 dark:bg-emerald-400 animate-pulse" />
              Updating
            </span>
          )}
        </div>
      )}
      <div
        className={isACSession ? "grid grid-cols-1 gap-6" : "grid grid-cols-1 sm:grid-cols-2 gap-6"}
      >
        <MetricCard title="Power Used" value={`${powerUsed.toFixed(2)} kWh`} />
        {isACSession ? null : <MetricCard title="Battery %" value={formatBatteryPercentage(stateOfCharge)} />}
      </div>

      {hasChargingDetails && (
          <div className="border-t pt-4 dark:border-gray-700">
            <h3 className="px-4 text-sm font-semibold text-gray-900 dark:text-white">
              Charging Details
            </h3>
            <dl className="mt-3 grid grid-cols-1 gap-x-6 gap-y-3 px-4 text-sm sm:grid-cols-2">
              <div className="flex items-start justify-between gap-4 border-b border-gray-100 pb-2 dark:border-gray-700">
                <dt className="text-gray-500 dark:text-gray-400">Charging start</dt>
                <dd className="text-right font-medium text-gray-900 dark:text-gray-100">
                  {formatSessionTimestamp(chargingStart)}
                </dd>
              </div>
              <div className="flex items-start justify-between gap-4 border-b border-gray-100 pb-2 dark:border-gray-700">
                <dt className="text-gray-500 dark:text-gray-400">Charging stop</dt>
                <dd className="text-right font-medium text-gray-900 dark:text-gray-100">
                  {formatSessionTimestamp(chargingStop)}
                </dd>
              </div>
              {showCompletedDetails && chargingStopReason && (
                <div className="flex items-start justify-between gap-4 border-b border-gray-100 pb-2 dark:border-gray-700">
                  <dt className="text-gray-500 dark:text-gray-400">Stop reason</dt>
                  <dd className="text-right font-medium text-gray-900 dark:text-gray-100">
                    {chargingStopReason}
                  </dd>
                </div>
              )}
            </dl>
          </div>
        )}

      <div className="border-t pt-4 dark:border-gray-700">
        <button
          onClick={() => setShowEnergyDetails(!showEnergyDetails)}
          className="flex items-center justify-between w-full px-4 py-2 text-sm font-semibold dark:text-white"
        >
          <span>Show Energy Details</span>
          {showEnergyDetails ? (
            <ChevronUp className="w-5 h-5" />
          ) : (
            <ChevronDown className="w-5 h-5" />
          )}
        </button>

        {showEnergyDetails && (
          <div className="mt-4 grid grid-cols-2 md:grid-cols-4 gap-4 px-2">
            {data.energy_report && (
              <>
                <EnergyCard
                  label="Current"
                  value={data.energy_report.current?.value || 0}
                  unit={data.energy_report.current?.unit || "A"}
                />
                <EnergyCard
                  label="Power"
                  value={data.energy_report.power?.value || 0}
                  unit={data.energy_report.power?.unit || "W"}
                />
              </>
            )}
          </div>
        )}

        <button
          onClick={() => setShowCostDetails(!showCostDetails)}
          className="flex items-center justify-between w-full px-4 py-3 text-sm font-semibold dark:text-white hover:bg-gray-50 dark:hover:bg-gray-700/50 rounded-lg transition-colors"
        >
          <div className="flex items-center gap-2">
            <span>Cost Details</span>
            {displayCost && totalCost > 0 && (
              <span className="text-xs font-normal text-brand-600 dark:text-brand-400">
                ({formatCurrency(totalCost)})
              </span>
            )}
          </div>
          {showCostDetails ? (
            <ChevronUp className="w-5 h-5" />
          ) : (
            <ChevronDown className="w-5 h-5" />
          )}
        </button>

        {showCostDetails && (
          <div className="mt-4 space-y-4">
            {/* Total Cost Card - Prominent */}
            {displayCost && totalCost > 0 && (
              <div className="bg-gradient-to-br from-brand-50 to-brand-100 dark:from-brand-900/20 dark:to-brand-800/20 rounded-lg p-4 border border-brand-200 dark:border-brand-800">
                <div className="flex items-center justify-between">
                  <span className="text-sm font-semibold text-brand-900 dark:text-brand-100">
                    Total Cost
                  </span>
                  <span className="text-2xl font-bold text-brand-700 dark:text-brand-300">
                    {formatCurrency(totalCost)}
                  </span>
                </div>
                {displayCost.currency && (
                  <p className="text-xs text-brand-600 dark:text-brand-400 mt-1">
                    Currency: {displayCost.currency}
                  </p>
                )}
              </div>
            )}

            {/* Cost Breakdown */}
            {displayCost?.breakdown && displayCost.breakdown.length > 0 && (
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4 px-2">
                {displayCost.breakdown.map((item, index) => (
                  <FeeBreakdownCard
                    key={`${item.type}-${item.fee_name || item.rate_name || index}`}
                    item={item}
                    index={index}
                    breakdown={displayCost.breakdown}
                    rateFees={data.fee_details?.rate_fees}
                    currency={displayCost.currency}
                  />
                ))}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

const MetricCard = ({ title, value }: { title: string; value: string }) => (
  <div className="rounded-xl p-6 text-center bg-gradient-to-br from-brand-600 to-brand-800 transform hover:scale-105 hover:shadow-2xl hover:shadow-brand-500/40 ">
    <p className="text-sm text-slate-300 mb-1">{title}</p>
    <p className="text-3xl font-extrabold text-white">{value}</p>
  </div>
);

const EnergyCard = ({
  label,
  value,
  unit,
  desc,
}: {
  label: string;
  value: any;
  unit?: string;
  desc?: string;
}) => (
  <div className="rounded-lg shadow p-4 border border-slate-100 text-center dark:bg-gray-800 dark:border-gray-700">
    <p className="text-sm font-semibold text-gray-500">{label}</p>
    {desc && <p className="text-xs text-gray-500 mt-1">{desc}</p>}
    <p className="text-xl font-semibold text-brand-500 dark:text-brand-400 mt-2">{value}</p>
    <p className="text-sm">{unit ? `${unit}` : ""}</p>
  </div>
);

const FeeBreakdownCard = ({
  item,
  index,
  breakdown,
  rateFees,
  currency,
}: {
  item: CostBreakdown;
  index: number;
  breakdown?: CostBreakdown[] | null;
  rateFees?: NonNullable<Session["fee_details"]>["rate_fees"];
  currency?: string | null;
}) => {
  const sourceUnit = getBreakdownUnitLabel(item);
  const displayRate = toPerMinuteRateDisplay(item.type, item.unit_price, sourceUnit);
  const unitLabel = displayRate.unit;
  const flatFee = isFlatFee(item);
  const displayQuantity =
    unitLabel === "min" && sourceUnit !== "min" ? item.quantity * 60 : item.quantity;
  const quantityLabel = `${formatBreakdownQuantity(displayQuantity)} ${unitLabel}`;
  const unitPriceLabel = flatFee
    ? `Max ${formatBreakdownCurrency(item.unit_price, currency)} total`
    : `${formatBreakdownCurrency(displayRate.unitPrice, currency)}/${unitLabel}`;
  const totalCostLabel = formatBreakdownCurrency(item.total_cost, currency);
  const feeName = resolveBreakdownLabel(item, formatBreakdownType(item.type), {
    rateFees,
    breakdown,
    index,
  });
  const typeLabel = formatBreakdownType(item.type);

  return (
    <div className="rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
      <div className="flex items-start justify-between gap-3">
        <div>
          <p className="text-sm font-semibold text-gray-900 dark:text-gray-100">{feeName}</p>
          <p className="mt-1 text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
            {typeLabel}
          </p>
        </div>
        <p className="text-lg font-bold text-brand-600 dark:text-brand-400">{totalCostLabel}</p>
      </div>

      {flatFee && (
        <p className="mt-3 text-xs leading-snug text-gray-500 dark:text-gray-400">
          {getDynamicFlatFeePricing(item.unit_price, currency || "IDR").description}
        </p>
      )}

      <div className="mt-4 grid grid-cols-2 gap-3 text-sm">
        <div className="rounded-md bg-slate-50 px-3 py-2 dark:bg-gray-900/50">
          <p className="text-xs text-gray-500 dark:text-gray-400">Quantity</p>
          <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">{quantityLabel}</p>
        </div>
        <div className="rounded-md bg-slate-50 px-3 py-2 dark:bg-gray-900/50">
          <p className="text-xs text-gray-500 dark:text-gray-400">
            {flatFee ? "Max Fee" : "Unit Price"}
          </p>
          <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">{unitPriceLabel}</p>
        </div>
      </div>

      {hasTaxBreakdown(item) && (
        <div className="mt-4 space-y-2 text-xs text-gray-600 dark:text-gray-300">
          <div className="flex items-center justify-between gap-3">
            <span>Subtotal</span>
            <span className="font-medium text-gray-900 dark:text-gray-100">
              {formatBreakdownCurrency(item.before_tax, currency)}
            </span>
          </div>
          <div className="flex items-center justify-between gap-3">
            <span>{formatTaxLabel(item.tax)}</span>
            <span className="font-medium text-gray-900 dark:text-gray-100">
              {formatBreakdownCurrency(item.total_tax, currency)}
            </span>
          </div>
        </div>
      )}
    </div>
  );
};

export default ChargingMetrics;
