import React, { useState, useMemo, useCallback } from 'react';
import PropTypes from 'prop-types';
import dayjs from 'dayjs';
import {
  MdTrendingUp,
  MdTrendingDown,
  MdExpandMore,
  MdReceipt,
  MdPayments,
  MdRoute,
  MdLocationOn,
  MdBarChart,
  MdPeopleAlt
} from 'react-icons/md';
import './ProfitabilitySection.css';

// ─────────────────────────────────────────────────────────────
// Constants
// ─────────────────────────────────────────────────────────────

/** Revenue rule: ₹30 base for ≤8 km, ₹6/km beyond. */
const BASE_REVENUE = 30;
const BASE_KM_LIMIT = 8;
const EXTRA_RATE_KM = 6;

/** Fixed salary cost sliced per slot (₹5000 / 30 days / 1 slot). */
const FIXED_COST_PER_SLOT = 500 / 3;

/** Variable fuel / wear cost per km. */
const VARIABLE_RATE_KM = 2.5;

/** Status display config keyed by normalised status string. */
const STATUS_MAP = {
  delivered: { label: 'Delivered', color: '#10b981', bg: '#ecfdf5', border: '#a7f3d0' },
  active: { label: 'Active', color: '#0ea5e9', bg: '#f0f9ff', border: '#bae6fd' },
  picked: { label: 'Picked up', color: '#8b5cf6', bg: '#f5f3ff', border: '#ddd6fe' },
  assigned: { label: 'Assigned', color: '#f59e0b', bg: '#fffbeb', border: '#fde68a' },
  cancelled: { label: 'Cancelled', color: '#ef4444', bg: '#fef2f2', border: '#fca5a5' },
  skipped: { label: 'Skipped', color: '#f97316', bg: '#fff7ed', border: '#ffedd5' }
};

const DEFAULT_STATUS = STATUS_MAP.assigned;

// ─────────────────────────────────────────────────────────────
// Pure helpers
// ─────────────────────────────────────────────────────────────

function getStatusConfig(raw) {
  return STATUS_MAP[String(raw ?? '').toLowerCase()] ?? DEFAULT_STATUS;
}

function orderRevenue(order) {
  const km = parseFloat(order.riderkms || 0);
  return km <= BASE_KM_LIMIT ? BASE_REVENUE : BASE_REVENUE + (km - BASE_KM_LIMIT) * EXTRA_RATE_KM;
}

const BATCHES_DEFAULT = [
  { id: 'morning', name: 'Morning Batch', startHour: 0, endHour: 8 },
  { id: 'afternoon', name: 'Afternoon Batch', startHour: 9, endHour: 12.5 },
  { id: 'evening', name: 'Evening Batch', startHour: 16, endHour: 19 }
];

const getBatchForHour = (h, batches = BATCHES_DEFAULT) => {
  for (const b of batches) {
    if (h >= b.startHour && h < b.endHour) return b.id;
  }
  return null;
};

const getRowBatch = (r, batches = BATCHES_DEFAULT) => {
  const t = r?.assigntime || r?.deliverydate;
  if (!t) return null;
  const str = String(t).trim();
  if (/^\d{4}-\d{2}-\d{2}$/.test(str)) return null;
  const d = dayjs(t);
  if (!d.isValid()) return null;
  return getBatchForHour(d.hour() + d.minute() / 60, batches);
};

function calcRiderMetrics(rider, selectedDate, batches) {
  const orders = (rider.orders ?? []).filter((o) => {
    if (!selectedDate) return true;
    const dateStr = o.assigntime
      ? dayjs(o.assigntime).format('YYYY-MM-DD')
      : o.deliverydate
      ? dayjs(o.deliverydate).format('YYYY-MM-DD')
      : 'unknown';
    return dateStr === selectedDate;
  });
  let revenue = 0;
  let kms = 0;
  const slotsByDate = {};

  for (const o of orders) {
    revenue += orderRevenue(o);
    kms += parseFloat(o.riderkms || 0);

    const slot = getRowBatch(o, batches);
    if (!slot) continue;

    const dateStr = o.assigntime
      ? dayjs(o.assigntime).format('YYYY-MM-DD')
      : o.deliverydate
      ? dayjs(o.deliverydate).format('YYYY-MM-DD')
      : null;
    if (!dateStr) continue;

    if (!slotsByDate[dateStr]) {
      slotsByDate[dateStr] = new Set();
    }
    slotsByDate[dateStr].add(slot);
  }

  let slotCount = 0;
  Object.values(slotsByDate).forEach((set) => {
    slotCount += Math.min(set.size, 3);
  });

  const varCost = kms * VARIABLE_RATE_KM;
  const fixedCost = slotCount * FIXED_COST_PER_SLOT;
  const totalCost = varCost + fixedCost;
  const net = revenue - totalCost;
  const margin = revenue > 0 ? (net / revenue) * 100 : 0;

  return { revenue, kms, varCost, fixedCost, totalCost, net, margin, orders };
}

/** Format a km value, switching to metres below 1 km so short hops don't round to "0.0 km". */
function formatDistance(km) {
  const value = Number.isFinite(km) ? km : 0;
  if (value > 0 && value < 1) {
    return { value: String(Math.round(value * 1000)), unit: 'm' };
  }
  return { value: value.toFixed(1), unit: 'km' };
}

function rupees(v, decimals = 0) {
  if (v == null) return '—';
  return `₹${parseFloat(v).toFixed(decimals)}`;
}

function riderInitials(name) {
  if (!name) return '?';
  return (
    name
      .trim()
      .split(/\s+/)
      .slice(0, 2)
      .map((w) => w[0] ?? '')
      .join('')
      .toUpperCase() || '?'
  );
}

function clamp(value, min, max) {
  return Math.min(Math.max(value, min), max);
}

// ─────────────────────────────────────────────────────────────
// Sub-components
// ─────────────────────────────────────────────────────────────

/** Coloured pill with a status dot. */
function OrderStatusPill({ status }) {
  const cfg = getStatusConfig(status);
  return (
    <span className="order-status-pill" style={{ background: cfg.bg, color: cfg.color, borderColor: cfg.border }}>
      <span className="order-status-dot" aria-hidden="true" />
      {cfg.label}
    </span>
  );
}

/** Customer name + phone + location stacked cell. */
function CustomerCell({ order }) {
  const name = order.customername ?? order.customer_name ?? order.deliverycustomer ?? order.pickupcustomer ?? 'Unknown customer';
  const phone = order.customerphone ?? order.phone ?? order.mobile ?? '';
  const location = order.locationname ?? order.kitchenname ?? order.kitchenName ?? '';

  return (
    <div>
      <div className="customer-name" title={name}>
        {name}
      </div>
      {phone && <div className="customer-phone">{phone}</div>}
      {location && (
        <div className="customer-location">
          <MdLocationOn size={12} aria-hidden="true" />
          {location}
        </div>
      )}
    </div>
  );
}

/** Orders table inside an expanded rider card. */
function OrdersBreakdownTable({ orders, getRevenue }) {
  if (!orders?.length) {
    return (
      <div className="orders-empty-state" role="status">
        <MdReceipt size={24} aria-hidden="true" />
        <p className="orders-empty-message">No orders assigned to this rider yet.</p>
      </div>
    );
  }

  return (
    <div className="orders-table-container">
      <table className="orders-table" role="table">
        <thead>
          <tr>
            <th scope="col">Customer</th>
            <th scope="col">Status</th>
            <th scope="col">Planned KMs</th>
            <th scope="col">Actual KMs</th>
            <th scope="col">Trip KMs</th>
            <th scope="col" style={{ textAlign: 'right' }}>
              Revenue
            </th>
          </tr>
        </thead>
        <tbody>
          {orders.map((order, idx) => {
            const km = parseFloat(order.riderkms ?? 0);
            const dist = formatDistance(km);
            const plannedDist = formatDistance(parseFloat(order.kms ?? 0));
            const actualDist = formatDistance(parseFloat(order.actualkms ?? 0));
            const rev = getRevenue(order);
            return (
              <tr key={`${order.orderid ?? 'order'}-${idx}`}>
                <td>
                  <CustomerCell order={order} />
                </td>
                <td>
                  <OrderStatusPill status={order.orderstatus ?? order.status} />
                </td>
                <td>
                  <span className="distance-value">{plannedDist.value}</span>
                  <span className="distance-unit">{plannedDist.unit}</span>
                </td>
                <td>
                  <span className="distance-value">{actualDist.value}</span>
                  <span className="distance-unit">{actualDist.unit}</span>
                </td>
                <td>
                  <span className="distance-value">{dist.value}</span>
                  <span className="distance-unit">{dist.unit}</span>
                </td>
                <td style={{ textAlign: 'right' }}>
                  <span className="revenue-amount">{rupees(rev)}</span>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

/** Expanded cost breakdown + orders for one rider. */
function RiderDetailPanel({ metrics }) {
  const { varCost, fixedCost, kms, net, margin } = metrics;
  const isProfit = net >= 0;

  const costTiles = [
    {
      icon: <MdPayments size={16} />,
      iconClass: 'cost-tile-icon--fixed',
      label: 'Fixed cost',
      amount: rupees(fixedCost, 2),
      amountClass: '',
      footnote: 'Salary (per slot)'
    },
    {
      icon: <MdRoute size={16} />,
      iconClass: 'cost-tile-icon--variable',
      label: 'Variable cost',
      amount: rupees(varCost, 2),
      amountClass: '',
      footnote: `${kms.toFixed(1)} km × ₹${VARIABLE_RATE_KM}/km`
    },
    {
      icon: isProfit ? <MdTrendingUp size={16} /> : <MdTrendingDown size={16} />,
      iconClass: isProfit ? 'cost-tile-icon--profit' : 'cost-tile-icon--loss',
      label: isProfit ? 'Net profit' : 'Net loss',
      amount: `${isProfit ? '+' : ''}${rupees(net, 2)}`,
      amountClass: isProfit ? 'cost-tile-amount--profit' : 'cost-tile-amount--loss',
      footnote: `${Math.abs(margin).toFixed(0)}% margin`
    }
  ];

  return (
    <div className="rider-detail-panel" aria-label="Rider cost breakdown">
      <div className="rider-detail-inner">
        {/* Cost breakdown tiles */}
        <div className="cost-breakdown-grid">
          {costTiles.map((tile) => (
            <div className="cost-tile" key={tile.label}>
              <div className={`cost-tile-icon ${tile.iconClass}`} aria-hidden="true">
                {tile.icon}
              </div>
              <div className="cost-tile-content">
                <span className="cost-tile-label">{tile.label}</span>
                <span className={`cost-tile-amount ${tile.amountClass}`}>{tile.amount}</span>
                <span className="cost-tile-footnote">{tile.footnote}</span>
              </div>
            </div>
          ))}
        </div>

        {/* Revenue breakdown table */}
        <div className="revenue-breakdown">
          <div className="revenue-breakdown-header">
            <div className="revenue-breakdown-title">
              <MdReceipt size={14} aria-hidden="true" />
              Revenue Breakdown
            </div>
            <span className="revenue-breakdown-count">
              {metrics.orders?.length ?? 0} order{(metrics.orders?.length ?? 0) !== 1 ? 's' : ''}
            </span>
          </div>
          <OrdersBreakdownTable orders={metrics.orders} getRevenue={orderRevenue} />
        </div>
      </div>
    </div>
  );
}

/** Single expandable rider profitability card. */
function RiderProfitabilityCard({ rider, metrics, isExpanded, isFocused, onToggle, onFocus }) {
  const { revenue, kms, totalCost, net, margin, orders } = metrics;
  const isProfit = net >= 0;
  const marginBarWidth = `${clamp(Math.abs(margin), 0, 100)}%`;
  const orderCount = orders?.length ?? 0;
  const name = rider.riderName ?? rider.username ?? `Rider #${rider.id}`;

  const cardClasses = [
    'rider-profitability-card',
    isProfit ? 'rider-profitability-card--profitable' : 'rider-profitability-card--unprofitable',
    isFocused ? 'rider-profitability-card--selected' : ''
  ]
    .filter(Boolean)
    .join(' ');

  function handleActivate() {
    onToggle(rider.id);
    if (!isFocused && onFocus) onFocus(rider);
  }

  return (
    <div className={cardClasses} aria-label={`Rider: ${name}`}>
      {/* Clickable header row */}
      <div
        className="rider-card-header"
        role="button"
        tabIndex={0}
        aria-expanded={isExpanded}
        onClick={handleActivate}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            handleActivate();
          }
        }}
      >
        {/* Rider identity */}
        <div className="rider-avatar" aria-hidden="true">
          {riderInitials(name)}
        </div>
        <div className="rider-identity">
          <div className="rider-name" title={name}>
            {name}
          </div>
          <div className="rider-order-summary">
            {orderCount} order{orderCount !== 1 ? 's' : ''}
            <span className="rider-order-summary-separator">·</span>
            {kms.toFixed(1)} km total
          </div>
        </div>

        {/* Summary metrics — hidden on mobile via CSS */}
        <div className="rider-metrics-row" aria-hidden="true">
          <div className="rider-metric">
            <span className="rider-metric-label">Revenue</span>
            <span className="rider-metric-amount rider-metric-amount--revenue">{rupees(revenue)}</span>
          </div>
          <div className="rider-metric">
            <span className="rider-metric-label">Cost</span>
            <span className="rider-metric-amount rider-metric-amount--cost">{rupees(totalCost)}</span>
          </div>
          <div className="rider-net-profit-column">
            <div className="rider-metric">
              <span className="rider-metric-label">Net</span>
              <span className={`rider-metric-amount ${isProfit ? 'rider-metric-amount--net-profit' : 'rider-metric-amount--net-loss'}`}>
                {isProfit ? '+' : ''}
                {rupees(net)}
              </span>
            </div>
            <div className="rider-margin-bar">
              <div
                className={`rider-margin-bar-fill ${isProfit ? 'rider-margin-bar-fill--profit' : 'rider-margin-bar-fill--loss'}`}
                style={{ width: marginBarWidth }}
                role="presentation"
              />
            </div>
          </div>
        </div>

        {/* Expand chevron */}
        <div className={`rider-expand-toggle ${isExpanded ? 'rider-expand-toggle--open' : ''}`} aria-hidden="true">
          <MdExpandMore size={22} />
        </div>
      </div>

      {/* Expanded detail panel */}
      {isExpanded && <RiderDetailPanel rider={rider} metrics={metrics} />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Main export
// ─────────────────────────────────────────────────────────────

/**
 * ProfitabilitySection
 *
 * Props:
 *   riders          — Array of rider objects with .orders[]
 *   totalDailyProfit — Number: daily aggregate across all slots
 *   focusedRider    — Rider object (or null) synced with map
 *   handleRiderFocus — (rider) => void  called when a card is clicked
 */
export default function ProfitabilitySection({
  riders = [],
  totalDailyProfit = 0,
  focusedRider = null,
  handleRiderFocus,
  selectedDate,
  batches
}) {
  const [expanded, setExpanded] = useState({});
  const sortMode = 'profit-asc'; // 'profit-asc', 'profit-desc', 'name-asc', 'orders-desc'

  const toggleRider = useCallback((id) => {
    setExpanded((prev) => ({ ...prev, [id]: !prev[id] }));
  }, []);

  // Enrich riders with computed metrics
  const enriched = useMemo(
    () => riders.map((r) => ({ ...r, _m: calcRiderMetrics(r, selectedDate, batches) })),
    [riders, selectedDate, batches]
  );

  // Filter out inactive riders (those with 0 orders in the selected date/slot) to ensure accurate KPI aggregations
  const activeEnriched = useMemo(
    () => enriched.filter((r) => r._m.orders.length > 0),
    [enriched]
  );

  // Aggregate overall slot totals (pre-filtered for BI consistency)
  const slotRevenue = activeEnriched.reduce((s, r) => s + r._m.revenue, 0);
  const slotCost = activeEnriched.reduce((s, r) => s + r._m.totalCost, 0);
  const slotNet = activeEnriched.reduce((s, r) => s + r._m.net, 0);
  const slotKms = activeEnriched.reduce((s, r) => s + r._m.kms, 0);
  const profitCount = activeEnriched.filter((r) => r._m.net >= 0).length;
  const lossCount = activeEnriched.length - profitCount;

  const dailyIsProfit = totalDailyProfit >= 0;
  const slotIsProfit = slotNet >= 0;

  // Filter riders (filtering by search and status tabs removed)
  const filtered = activeEnriched;

  // Sort riders based on selected sortMode
  const sortedAndFiltered = useMemo(() => {
    const list = [...filtered];
    if (sortMode === 'profit-asc') {
      list.sort((a, b) => a._m.net - b._m.net);
    } else if (sortMode === 'profit-desc') {
      list.sort((a, b) => b._m.net - a._m.net);
    } else if (sortMode === 'name-asc') {
      list.sort((a, b) => {
        const nameA = (a.riderName ?? a.username ?? `Rider #${a.id}`).toLowerCase();
        const nameB = (b.riderName ?? b.username ?? `Rider #${b.id}`).toLowerCase();
        return nameA.localeCompare(nameB);
      });
    } else if (sortMode === 'orders-desc') {
      list.sort((a, b) => (b._m.orders?.length ?? 0) - (a._m.orders?.length ?? 0));
    }
    return list;
  }, [filtered, sortMode]);

  return (
    <div className="profitability-dashboard" role="region" aria-label="Profitability overview">
      {/* ── Header ── */}
      <header className="profitability-header">
        <div className="profitability-header-left">
          <div className="profitability-header-icon" aria-hidden="true">
            <MdBarChart size={18} />
          </div>
          <div>
            <h2 className="profitability-header-title">Profitability Overview</h2>
            <p className="profitability-header-subtitle">
              <span>
                {activeEnriched.length} rider{activeEnriched.length !== 1 ? 's' : ''}
              </span>
              <span className="profitability-header-dot" />
              <span style={{ color: 'var(--profit-green)' }}>{profitCount} profitable</span>
              <span className="profitability-header-dot" />
              <span style={{ color: 'var(--loss-red)' }}>{lossCount} at loss</span>
            </p>
          </div>
        </div>

        <div className="profitability-kpi-group">
          {/* Daily profit / loss */}
          <div className={`profitability-kpi-chip ${dailyIsProfit ? 'profitability-kpi-chip--profit' : 'profitability-kpi-chip--loss'}`}>
            <div className="profitability-kpi-chip-icon" aria-hidden="true">
              {dailyIsProfit ? <MdTrendingUp /> : <MdTrendingDown />}
            </div>
            <div className="profitability-kpi-chip-content">
              <span className="profitability-kpi-chip-label">Daily {dailyIsProfit ? 'profit' : 'loss'}</span>
              <span className="profitability-kpi-chip-amount">{rupees(Math.abs(totalDailyProfit))}</span>
            </div>
          </div>

          {/* Slot profit / loss */}
          <div className={`profitability-kpi-chip ${slotIsProfit ? 'profitability-kpi-chip--profit' : 'profitability-kpi-chip--loss'}`}>
            <div className="profitability-kpi-chip-icon" aria-hidden="true">
              {slotIsProfit ? <MdTrendingUp /> : <MdTrendingDown />}
            </div>
            <div className="profitability-kpi-chip-content">
              <span className="profitability-kpi-chip-label">Slot {slotIsProfit ? 'profit' : 'loss'}</span>
              <span className="profitability-kpi-chip-amount">{rupees(Math.abs(slotNet))}</span>
            </div>
          </div>
        </div>
      </header>

      {/* ── Summary statistics row ── */}
      <div className="profitability-summary-row" role="group" aria-label="Slot summary">
        <div className="profitability-summary-card profitability-summary-card--primary">
          <span className="profitability-summary-label">Riders Active</span>
          <span className="profitability-summary-value">{activeEnriched.length}</span>
          <span className="profitability-summary-detail">
            {profitCount} in profit · {lossCount} at loss
          </span>
        </div>
        <div className="profitability-summary-card profitability-summary-card--primary">
          <span className="profitability-summary-label">Total Distance</span>
          <span className="profitability-summary-value">{slotKms.toFixed(1)} km</span>
          <span className="profitability-summary-detail">Cumulative travel distance</span>
        </div>
        <div className="profitability-summary-card profitability-summary-card--primary">
          <span className="profitability-summary-label">Slot Revenue</span>
          <span className="profitability-summary-value">{rupees(slotRevenue)}</span>
          <span className="profitability-summary-detail">From {enriched.reduce((s, r) => s + (r._m.orders?.length ?? 0), 0)} orders</span>
        </div>
        <div className="profitability-summary-card profitability-summary-card--loss">
          <span className="profitability-summary-label">Slot Cost</span>
          <span className="profitability-summary-value profitability-summary-value--loss">{rupees(slotCost)}</span>
          <span className="profitability-summary-detail">Fixed + variable</span>
        </div>
        <div className={`profitability-summary-card ${slotIsProfit ? 'card-profit' : 'card-loss'}`}>
          <span className="profitability-summary-label">Slot Net</span>
          <span className={`profitability-summary-value ${slotIsProfit ? 'net-positive' : 'net-negative'}`}>
            {slotIsProfit ? '+' : ''}
            {rupees(slotNet)}
          </span>
          <span
            className={`profitability-summary-detail ${slotRevenue > 0 ? (slotNet / slotRevenue >= 0 ? 'margin-positive' : 'margin-negative') : ''
              }`}
          >
            {slotRevenue > 0
              ? `${slotNet / slotRevenue >= 0 ? '+' : ''}${((slotNet / slotRevenue) * 100).toFixed(0)}% margin`
              : '0% margin'}
          </span>
        </div>
      </div>

      {/* ── Controls (Search) (removed) ── */}

      {/* ── Rider feed ── */}
      <div className="rider-profitability-feed" role="list" aria-label="Rider cards">
        <div className="rider-feed-heading" aria-hidden="true">
          Riders List
        </div>

        {sortedAndFiltered.length === 0 ? (
          <div className="profitability-empty-state" role="status">
            <MdPeopleAlt size={32} aria-hidden="true" />
            <p className="profitability-empty-message">No riders matching the filters.</p>
          </div>
        ) : (
          sortedAndFiltered.map((rider) => (
            <div key={rider.id} role="listitem">
              <RiderProfitabilityCard
                rider={rider}
                metrics={rider._m}
                isExpanded={!!expanded[rider.id]}
                isFocused={focusedRider?.id === rider.id}
                onToggle={toggleRider}
                onFocus={handleRiderFocus}
              />
            </div>
          ))
        )}
      </div>
    </div>
  );
}

OrderStatusPill.propTypes = {
  status: PropTypes.string
};

CustomerCell.propTypes = {
  order: PropTypes.object.isRequired
};

OrdersBreakdownTable.propTypes = {
  orders: PropTypes.array,
  getRevenue: PropTypes.func.isRequired
};

RiderDetailPanel.propTypes = {
  rider: PropTypes.object.isRequired,
  metrics: PropTypes.shape({
    varCost: PropTypes.number.isRequired,
    fixedCost: PropTypes.number.isRequired,
    kms: PropTypes.number.isRequired,
    net: PropTypes.number.isRequired,
    margin: PropTypes.number.isRequired
  }).isRequired
};

RiderProfitabilityCard.propTypes = {
  rider: PropTypes.object.isRequired,
  metrics: PropTypes.shape({
    revenue: PropTypes.number.isRequired,
    kms: PropTypes.number.isRequired,
    totalCost: PropTypes.number.isRequired,
    net: PropTypes.number.isRequired,
    margin: PropTypes.number.isRequired
  }).isRequired,
  isExpanded: PropTypes.bool.isRequired,
  isFocused: PropTypes.bool,
  onToggle: PropTypes.func.isRequired,
  onFocus: PropTypes.func
};

ProfitabilitySection.propTypes = {
  riders: PropTypes.array,
  totalDailyProfit: PropTypes.number,
  focusedRider: PropTypes.object,
  handleRiderFocus: PropTypes.func,
  selectedDate: PropTypes.string,
  batches: PropTypes.array
};
