import { useEffect, useState, useCallback, useRef } from "react";
import { useNavigate } from "react-router-dom";
import {
  ChevronLeft, ChevronRight, Search, ArrowUp, ArrowDown,
  X, Inbox, ArrowRight, RefreshCw, CheckCircle2,
} from "lucide-react";
import { getRVScreen, getRecordView, type RecordViewField, type SearchQuery, type TileValue, type ChartDataResponse } from "../api/viewService";
import FormModal from "./FormModal";
import Tile from "./Tile";
import BarChart from "./BarChart";
import PieChart from "./PieChart";

// ---------------------------------------------------------------------------
// Action column (config-driven from rv-screen layout)
// ---------------------------------------------------------------------------

interface ActionCondition {
  field_key: string;
  operator: string;
  value: unknown;
  data_type?: string;
}
interface ActionConditions {
  logic?: "AND" | "OR";
  conditions: ActionCondition[];
}
interface ActionButton {
  name: string;
  icon?: string;
  classes?: string[];
  job_template?: string;
  params?: { activity_uid?: string; workflow_uuid?: string; [k: string]: unknown };
  show_conditions?: ActionConditions | null;
  action_end?: Array<{ type: string }>;
}
interface ActionColumn {
  id: string;
  display: string;
  buttons: ActionButton[];
}

const ICONS: Record<string, React.ReactNode> = {
  refresh:  <RefreshCw size={13} />,
  task_alt: <CheckCircle2 size={13} />,
};

function iconFor(name?: string): React.ReactNode {
  return (name && ICONS[name]) || <RefreshCw size={13} />;
}

// Walks the rv-screen layout to find columns with `type: "custom"` and their
// inner button configs.
function extractActionColumns(layout: any): ActionColumn[] {
  const out: ActionColumn[] = [];
  const walk = (nodes: any[]): void => {
    for (const n of nodes ?? []) {
      const cfg = n?.config;
      if (cfg?.type === "rv_table" && Array.isArray(cfg.columns)) {
        for (const col of cfg.columns) {
          if (col?.type === "custom" && Array.isArray(col.config)) {
            const buttons = col.config.filter((b: any) => b?.type === "button");
            if (buttons.length > 0) {
              out.push({ id: col.id, display: col.display || "Actions", buttons });
            }
          }
        }
      }
      if (Array.isArray(n?.children)) walk(n.children);
    }
  };
  walk(Array.isArray(layout) ? layout : []);
  return out;
}

function evalShowConditions(c: ActionConditions | null | undefined, row: Record<string, unknown>): boolean {
  if (!c || !Array.isArray(c.conditions) || c.conditions.length === 0) return true;
  const results = c.conditions.map((cond) => {
    const v = row[cond.field_key];
    switch (cond.operator) {
      case "equals":       return v === cond.value;
      case "not_equals":   return v !== cond.value;
      case "is_empty":     return v == null || v === "";
      case "is_not_empty": return v != null && v !== "";
      case "in":           return Array.isArray(cond.value) && cond.value.includes(v as never);
      case "not_in":       return Array.isArray(cond.value) && !cond.value.includes(v as never);
      default:             return false;
    }
  });
  return (c.logic === "OR") ? results.some(Boolean) : results.every(Boolean);
}

function buttonClass(classes?: string[]): string {
  const ghost = classes?.includes("z-btn-secondary");
  const base = "h-7 px-2.5 text-[11px] font-semibold rounded-lg inline-flex items-center gap-1 transition-all";
  return ghost
    ? `${base} text-stone-600 dark:text-zinc-300 bg-white dark:bg-zinc-800 border border-stone-200 dark:border-zinc-700 hover:bg-stone-50 dark:hover:bg-zinc-700`
    : `${base} text-white mh-glow hover:scale-[1.02]`;
}

// ---------------------------------------------------------------------------
// Skeleton
// ---------------------------------------------------------------------------

function TableSkeleton({ rows, cols }: { rows: number; cols: number }) {
  return (
    <div className="rounded-2xl border border-stone-200/80 dark:border-zinc-700/60 bg-white dark:bg-zinc-900 overflow-hidden shadow-sm">
      <div className="px-5 py-3 border-b border-stone-100 dark:border-zinc-800 flex items-center gap-3">
        <div className="h-5 w-16 bg-stone-100 dark:bg-zinc-800 rounded animate-pulse" />
        <div className="ml-auto h-8 w-44 bg-stone-100 dark:bg-zinc-800 rounded-lg animate-pulse" />
      </div>
      <table className="w-full">
        <thead>
          <tr className="bg-stone-50/80 dark:bg-zinc-800/40 border-b border-stone-200/80 dark:border-zinc-700/80">
            {Array.from({ length: cols }).map((_, i) => (
              <th key={i} className={`py-2.5 ${i === 0 ? "pl-5" : "px-4"}`}>
                <div className="h-3 bg-stone-200 dark:bg-zinc-700 rounded animate-pulse w-20" />
              </th>
            ))}
          </tr>
        </thead>
        <tbody className="divide-y divide-stone-100/80 dark:divide-zinc-800/60">
          {Array.from({ length: rows }).map((_, r) => (
            <tr key={r}>
              {Array.from({ length: cols }).map((_, c) => (
                <td key={c} className={`py-3.5 ${c === 0 ? "pl-5 pr-4" : "px-4"}`}>
                  <div className="h-3 bg-stone-100 dark:bg-zinc-800 rounded animate-pulse" style={{ width: `${60 + Math.random() * 40}%` }} />
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

interface Props {
  // Either the numeric source_screen_id or the source_uuid; the view-service
  // accepts both at /app/:appId/rv-screens/:idOrUuid.
  viewId: number | string;
  onRowClick?: (instanceId: string) => void;
  toolbarAction?: React.ReactNode;
}

type AnalyticsSpec =
  | { kind: "tile";  uid: string; title?: string }
  | { kind: "chart"; uid: string; title?: string; chartType?: string };

// Walk rv-screen layout to find rv_tile / rv_chart elements (the platform
// places them as sibling blocks above the rv_table).
function extractAnalyticsElements(layout: any): AnalyticsSpec[] {
  const out: AnalyticsSpec[] = [];
  const walk = (nodes: any[]): void => {
    for (const n of nodes ?? []) {
      const cfg = n?.config;
      if (cfg?.type === "rv_tile"  && cfg.tile_uid)  out.push({ kind: "tile",  uid: cfg.tile_uid,  title: cfg.title });
      if (cfg?.type === "rv_chart" && cfg.chart_uid) out.push({ kind: "chart", uid: cfg.chart_uid, title: cfg.title, chartType: cfg.chart_type });
      if (Array.isArray(n?.children)) walk(n.children);
    }
  };
  walk(Array.isArray(layout) ? layout : []);
  return out;
}

// Walks the rv-screen layout to find the rv_table element and returns a
// key_name → display map for column header labels (the recordview response's
// output_label is empty for v2 envelope screens).
function extractColumnLabels(layout: any): Record<string, string> {
  const out: Record<string, string> = {};
  const walk = (nodes: any[]): void => {
    for (const n of nodes ?? []) {
      const cfg = n?.config;
      if (cfg?.type === "rv_table" && Array.isArray(cfg.columns)) {
        for (const c of cfg.columns) {
          if (c?.key_name && c?.display) out[c.key_name] = c.display;
        }
      }
      if (Array.isArray(n?.children)) walk(n.children);
    }
  };
  walk(Array.isArray(layout) ? layout : []);
  return out;
}

export default function RecordViewTable({ viewId, onRowClick, toolbarAction }: Props) {
  const navigate = useNavigate();
  const [rvTemplateUid, setRvTemplateUid] = useState<string | null>(null);
  const [columnLabels, setColumnLabels]   = useState<Record<string, string>>({});
  const [actionColumns, setActionColumns] = useState<ActionColumn[]>([]);
  const [analyticsSpecs, setAnalyticsSpecs] = useState<AnalyticsSpec[]>([]);
  const [tileValues, setTileValues]       = useState<TileValue[]>([]);
  const [chartData, setChartData]         = useState<ChartDataResponse[]>([]);
  const [fields, setFields]               = useState<RecordViewField[]>([]);
  const [rows, setRows]                   = useState<Record<string, unknown>[]>([]);
  const [pagination, setPagination]       = useState({ page: 1, limit: 10, total_count: 0, total_pages: 0 });
  const [query, setQuery]                 = useState<SearchQuery>({ page: 1, limit: 10, sort_dir: "desc" });
  const [searchInput, setSearchInput]     = useState("");
  const [loading, setLoading]             = useState(true);
  const [dataLoading, setDataLoading]     = useState(false);
  const [error, setError]                 = useState<string | null>(null);
  const [formModal, setFormModal]         = useState<{ activityId: string; instanceId: string; title: string } | null>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    setLoading(true);
    setRvTemplateUid(null);
    setColumnLabels({});
    setActionColumns([]);
    setAnalyticsSpecs([]);
    setTileValues([]);
    setChartData([]);
    getRVScreen(viewId)
      .then((rv) => {
        setColumnLabels(extractColumnLabels(rv.layout));
        setActionColumns(extractActionColumns(rv.layout));
        setAnalyticsSpecs(extractAnalyticsElements(rv.layout));
        setRvTemplateUid(rv.rv_template_uid);
      })
      .catch((err) => { setError(err.message); setLoading(false); });
  }, [viewId]);

  const fetchData = useCallback(async () => {
    if (!rvTemplateUid) return;
    if (!loading) setDataLoading(true);
    setError(null);
    try {
      const res = await getRecordView(rvTemplateUid, viewId, query);
      setTileValues(res.tile_values ?? []);
      setChartData(res.chart_data ?? []);
      setFields(res.config.fields.filter((f) => f.field_key !== ""));
      const dataRows = Array.isArray(res.data) ? res.data : [];
      setRows(dataRows);
      if (res.pagination) {
        setPagination(res.pagination);
      } else {
        setPagination((p) => ({ ...p, total_count: dataRows.length, total_pages: Math.ceil(dataRows.length / p.limit) || 1 }));
      }
    } catch (err: any) { setError(err.message); }
    finally { setLoading(false); setDataLoading(false); }
  }, [rvTemplateUid, viewId, query]);

  useEffect(() => { fetchData(); }, [fetchData]);

  const handleSort = (key: string) => setQuery((q) => ({
    ...q, page: 1, sort_by: key,
    sort_dir: q.sort_by === key && q.sort_dir === "asc" ? "desc" : "asc",
  }));

  const handleSearch = (e: React.FormEvent) => {
    e.preventDefault();
    setQuery((q) => ({ ...q, page: 1, search: searchInput }));
  };

  const clearSearch = () => {
    setSearchInput("");
    setQuery((q) => ({ ...q, page: 1, search: "" }));
  };

  const handlePage = (p: number) => setQuery((q) => ({ ...q, page: p }));

  const handleRowClick = (row: Record<string, unknown>) => {
    const id = String(row.instance_id ?? row._pk_value ?? "");
    if (!id) return;
    onRowClick ? onRowClick(id) : navigate(`/detail/${id}`);
  };

  const tileSpecs  = analyticsSpecs.filter(a => a.kind === "tile");
  const chartSpecs = analyticsSpecs.filter(a => a.kind === "chart");
  const analyticsRow = analyticsSpecs.length > 0 ? (
    <div className="space-y-3 mb-4">
      {tileSpecs.length > 0 && (
        <div className="flex flex-wrap items-stretch gap-3">
          {tileSpecs.map((a, i) => {
            const tv = tileValues.find(t => t.tile_uid === a.uid);
            return <Tile key={`tile-${i}`} title={a.title} value={tv?.value as number | undefined} loading={loading || dataLoading} />;
          })}
        </div>
      )}
      {chartSpecs.length > 0 && (
        <div className="flex flex-wrap items-stretch gap-3">
          {chartSpecs.map((a, i) => {
            const cd = chartData.find(c => c.chart_uid === a.uid);
            const Chart = (a as { chartType?: string }).chartType === "pie" ? PieChart : BarChart;
            return <Chart key={`chart-${i}`} title={a.title} rows={cd?.rows ?? []} loading={loading || dataLoading} />;
          })}
        </div>
      )}
    </div>
  ) : null;

  if (loading) return <>{analyticsRow}<TableSkeleton rows={6} cols={fields.length || 6} /></>;

  if (error) {
    return (
      <>
        {analyticsRow}
        <div className="rounded-2xl border border-red-100 dark:border-red-900/50 bg-red-50/50 dark:bg-red-950/20 p-10 text-center">
          <p className="text-sm text-red-600 dark:text-red-400 mb-2">{error}</p>
          <button onClick={fetchData} className="text-xs text-rose-600 dark:text-rose-400 hover:text-rose-800 font-semibold">Try again</button>
        </div>
      </>
    );
  }

  const primaryFieldKey = fields.find(
    (f) => f.field_key !== "current_state_name" && f.field_key !== "instance_id" && f.data_type === "text"
  )?.field_key;

  const { page, total_count, total_pages, limit } = pagination;
  const from  = total_count > 0 ? (page - 1) * limit + 1 : 0;
  const to    = Math.min(page * limit, total_count);
  const pages = buildPageRange(page, total_pages);

  return (
    <>
    {analyticsRow}
    <div className="rounded-2xl border border-stone-200/80 dark:border-zinc-700/60 bg-white dark:bg-zinc-900 overflow-hidden shadow-sm dark:shadow-black/20">

      {/* ── Toolbar ───────────────────────────────────────────────────────── */}
      <div className="px-5 py-3 flex items-center justify-between gap-4 border-b border-stone-100 dark:border-zinc-800">
        <div className="flex items-center gap-3">
          <div className="flex items-center gap-1.5">
            <span className="text-[15px] font-bold text-stone-800 dark:text-zinc-100 tabular-nums leading-none">{total_count}</span>
            <span className="text-[13px] text-stone-400 dark:text-zinc-500 leading-none">records</span>
          </div>

          {query.search && (
            <div className="flex items-center gap-1.5 pl-3 border-l border-stone-200 dark:border-zinc-700">
              <span className="text-[11px] text-stone-400 dark:text-zinc-500">Filtered:</span>
              <span
                className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-[11px] font-semibold border"
                style={{ background: "rgba(200,16,46,0.08)", borderColor: "rgba(200,16,46,0.22)", color: "#C8102E" }}
              >
                {query.search}
                <button onClick={clearSearch} className="ml-0.5 hover:opacity-60"><X size={9} /></button>
              </span>
            </div>
          )}

          {toolbarAction && (
            <div className="pl-3 border-l border-stone-200 dark:border-zinc-700">
              {toolbarAction}
            </div>
          )}
        </div>

        <div className="flex items-center gap-1.5">
          <button
            onClick={fetchData}
            disabled={dataLoading}
            title="Refresh"
            className="w-8 h-8 rounded-lg flex items-center justify-center text-stone-400 dark:text-zinc-500 hover:text-stone-600 dark:hover:text-zinc-300 hover:bg-stone-100 dark:hover:bg-zinc-800 transition-colors disabled:opacity-40"
          >
            <RefreshCw size={14} className={dataLoading ? "animate-spin" : ""} />
          </button>

          <form onSubmit={handleSearch}>
            <div className="relative">
              <Search size={13} className="absolute left-2.5 top-1/2 -transtone-y-1/2 text-stone-400 dark:text-zinc-500 pointer-events-none" />
              <input
                ref={searchRef}
                type="text"
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                placeholder="Search…"
                className="w-44 h-8 pl-8 pr-7 text-[13px] border border-stone-200 dark:border-zinc-700 rounded-lg bg-stone-50 dark:bg-zinc-800 text-stone-800 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-rose-500/20 focus:border-rose-400 dark:focus:border-rose-500 focus:bg-white dark:focus:bg-zinc-800 transition placeholder:text-stone-400 dark:placeholder:text-zinc-600"
              />
              {searchInput && (
                <button
                  type="button"
                  onClick={clearSearch}
                  className="absolute right-2 top-1/2 -transtone-y-1/2 text-stone-300 dark:text-zinc-600 hover:text-stone-500"
                >
                  <X size={12} />
                </button>
              )}
            </div>
          </form>
        </div>
      </div>

      {/* ── Table ─────────────────────────────────────────────────────────── */}
      <div className="overflow-x-auto relative">
        {dataLoading && (
          <div className="absolute inset-0 bg-white/60 dark:bg-zinc-900/60 z-10 flex items-center justify-center backdrop-blur-[1px]">
            <div className="w-5 h-5 border-2 border-rose-200 dark:border-rose-900 border-t-rose-600 rounded-full animate-spin" />
          </div>
        )}

        <table className="w-full">
          <thead>
            <tr className="bg-stone-50/80 dark:bg-zinc-800/40 border-b border-stone-200/80 dark:border-zinc-700/80">
              {fields.map((f, i) => {
                const isSorted = query.sort_by === f.field_key;
                return (
                  <th
                    key={f.field_key}
                    onClick={() => handleSort(f.field_key)}
                    className={`py-2.5 text-left text-[12px] font-semibold cursor-pointer select-none whitespace-nowrap transition-colors group/th
                      ${i === 0 ? "pl-5 pr-4" : "px-4"}
                      ${isSorted
                        ? "text-rose-600 dark:text-rose-400"
                        : "text-stone-500 dark:text-zinc-400 hover:text-stone-700 dark:hover:text-zinc-200"
                      }
                    `}
                  >
                    <span className="inline-flex items-center gap-1">
                      {columnLabels[f.field_key] || f.output_label || f.field_key}
                      {isSorted
                        ? (query.sort_dir === "asc"
                          ? <ArrowUp   size={11} className="text-rose-500" />
                          : <ArrowDown size={11} className="text-rose-500" />)
                        : <ArrowDown size={10} className="text-stone-300 dark:text-zinc-700 opacity-0 group-hover/th:opacity-100 transition-opacity" />
                      }
                    </span>
                  </th>
                );
              })}
              {actionColumns.map((ac) => (
                <th key={ac.id} className="py-2.5 px-4 text-left text-[12px] font-semibold text-stone-500 dark:text-zinc-400 whitespace-nowrap">
                  {ac.display}
                </th>
              ))}
              <th className="py-2.5 pr-4 w-16" />
            </tr>
          </thead>

          <tbody className="divide-y divide-stone-100/80 dark:divide-zinc-800/60">
            {rows.length === 0 ? (
              <tr>
                <td colSpan={fields.length + 1 + actionColumns.length} className="py-20 text-center">
                  <div className="flex flex-col items-center gap-3">
                    <div className="w-14 h-14 rounded-2xl flex items-center justify-center"
                      style={{ background: "linear-gradient(135deg,#fff5f5,#ffe4e6)" }}>
                      <Inbox size={22} className="text-rose-400" />
                    </div>
                    <div>
                      <div className="text-[14px] font-semibold text-stone-600 dark:text-zinc-300">No records found</div>
                      <div className="text-[12px] text-stone-400 dark:text-zinc-600 mt-1">
                        {query.search ? "Try a different search term" : "No data available"}
                      </div>
                    </div>
                    {query.search && (
                      <button onClick={clearSearch} className="text-[12px] font-semibold text-rose-600 dark:text-rose-400 hover:text-rose-800 transition-colors">
                        Clear search
                      </button>
                    )}
                  </div>
                </td>
              </tr>
            ) : rows.map((row, i) => (
                <tr
                  key={String(row.instance_id ?? i)}
                  onClick={() => handleRowClick(row)}
                  className="group/row cursor-pointer hover:bg-stone-50/80 dark:hover:bg-zinc-800/40 transition-colors"
                >
                  {fields.map((f, fi) => {
                    const isPrimary = f.field_key === primaryFieldKey;
                    const isFirst   = fi === 0;
                    return (
                      <td
                        key={f.field_key}
                        className={`py-3.5 whitespace-nowrap text-[13px]
                          ${isFirst
                            ? "pl-5 pr-4 border-l-2 border-l-transparent group-hover/row:border-l-rose-500 transition-colors"
                            : "px-4"
                          }
                          ${isPrimary
                            ? "font-semibold text-stone-800 dark:text-zinc-100"
                            : "text-stone-500 dark:text-zinc-400"
                          }
                        `}
                      >
                        {renderCell(row[f.field_key], f.data_type, f.field_key)}
                      </td>
                    );
                  })}

                  {actionColumns.map((ac) => {
                    const visible = ac.buttons.filter((b) => evalShowConditions(b.show_conditions, row));
                    return (
                      <td key={ac.id} className="px-4 py-3 whitespace-nowrap" onClick={(e) => e.stopPropagation()}>
                        {visible.length === 0 ? (
                          <span className="text-stone-300 dark:text-zinc-700">—</span>
                        ) : (
                          <div className="flex items-center gap-1.5">
                            {visible.map((b, bi) => {
                              const aid = b.params?.activity_uid;
                              if (!aid) return null;
                              return (
                                <button
                                  key={bi}
                                  onClick={() => setFormModal({
                                    activityId: aid,
                                    instanceId: String(row.instance_id),
                                    title: b.name,
                                  })}
                                  className={buttonClass(b.classes)}
                                  style={!b.classes?.includes("z-btn-secondary") ? { background: "linear-gradient(135deg, #C8102E, #E84258)" } : {}}
                                >
                                  {iconFor(b.icon)}{b.name}
                                </button>
                              );
                            })}
                          </div>
                        )}
                      </td>
                    );
                  })}

                  <td className="pr-4 py-3 w-16 text-right" onClick={(e) => e.stopPropagation()}>
                    <button
                      onClick={() => handleRowClick(row)}
                      className="w-7 h-7 rounded-lg flex items-center justify-center text-stone-400 dark:text-zinc-500 hover:text-rose-600 dark:hover:text-rose-400 hover:bg-rose-100 dark:hover:bg-rose-950/50 transition-colors opacity-0 group-hover/row:opacity-100 transition-opacity"
                    >
                      <ArrowRight size={14} />
                    </button>
                  </td>
                </tr>
              ))}
          </tbody>
        </table>
      </div>

      {/* ── Pagination ────────────────────────────────────────────────────── */}
      {total_count > 0 && (
        <div className="px-5 py-3 border-t border-stone-100 dark:border-zinc-800 flex items-center justify-between gap-4">
          <div className="flex items-center gap-3 text-[12px] text-stone-400 dark:text-zinc-500">
            <div className="flex items-center gap-1.5">
              Show
              <select
                value={query.limit}
                onChange={(e) => setQuery((q) => ({ ...q, page: 1, limit: Number(e.target.value) }))}
                className="h-7 px-2 text-[12px] border border-stone-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-800 text-stone-600 dark:text-zinc-300 font-medium focus:outline-none cursor-pointer"
              >
                <option value={10}>10</option>
                <option value={25}>25</option>
                <option value={50}>50</option>
              </select>
              per page
            </div>
            <span className="pl-3 border-l border-stone-200 dark:border-zinc-700 tabular-nums">
              {from}–{to} of {total_count}
            </span>
          </div>

          {total_pages > 1 && (
            <div className="flex items-center gap-0.5">
              <button
                disabled={page <= 1}
                onClick={() => handlePage(page - 1)}
                className="w-7 h-7 rounded-lg flex items-center justify-center text-stone-400 dark:text-zinc-500 hover:text-rose-600 dark:hover:text-rose-400 hover:bg-rose-50 dark:hover:bg-rose-950/30 disabled:opacity-30 disabled:pointer-events-none transition-colors"
              >
                <ChevronLeft size={15} />
              </button>

              {pages.map((p, idx) =>
                p === "…" ? (
                  <span key={`e${idx}`} className="w-7 h-7 flex items-center justify-center text-[12px] text-stone-300 dark:text-zinc-700 select-none">…</span>
                ) : (
                  <button
                    key={p}
                    onClick={() => handlePage(p as number)}
                    className={`w-7 h-7 rounded-lg text-[12px] font-medium transition-colors ${
                      p === page
                        ? "bg-rose-600 text-white"
                        : "text-stone-500 dark:text-zinc-400 hover:bg-rose-50 dark:hover:bg-rose-950/30 hover:text-rose-600 dark:hover:text-rose-400"
                    }`}
                  >
                    {p}
                  </button>
                )
              )}

              <button
                disabled={page >= total_pages}
                onClick={() => handlePage(page + 1)}
                className="w-7 h-7 rounded-lg flex items-center justify-center text-stone-400 dark:text-zinc-500 hover:text-rose-600 dark:hover:text-rose-400 hover:bg-rose-50 dark:hover:bg-rose-950/30 disabled:opacity-30 disabled:pointer-events-none transition-colors"
              >
                <ChevronRight size={15} />
              </button>
            </div>
          )}
        </div>
      )}

      {formModal && (
        <FormModal
          activityId={formModal.activityId}
          instanceId={formModal.instanceId}
          title={formModal.title}
          onClose={() => setFormModal(null)}
          onSuccess={() => { setFormModal(null); fetchData(); }}
        />
      )}
    </div>
    </>
  );
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function buildPageRange(current: number, total: number): Array<number | "…"> {
  if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);
  if (current <= 4) return [1, 2, 3, 4, 5, "…", total];
  if (current >= total - 3) return [1, "…", total - 4, total - 3, total - 2, total - 1, total];
  return [1, "…", current - 1, current, current + 1, "…", total];
}

function renderCell(value: unknown, dataType: string, fieldKey: string): React.ReactNode {
  if (value == null || value === "") return <span className="text-stone-300 dark:text-zinc-700">—</span>;
  if (fieldKey === "current_state_name") return <StatusBadge value={String(value)} />;
  if (dataType === "phone" && typeof value === "object") {
    const p = value as { phone_with_dial_code?: string; phone?: string; dial_code?: string };
    const text = p.phone_with_dial_code || (p.dial_code && p.phone ? `${p.dial_code}${p.phone}` : p.phone || "");
    return text ? <span className="tabular-nums">{text}</span> : <span className="text-stone-300 dark:text-zinc-700">—</span>;
  }
  if (dataType === "number") {
    const n = Number(value);
    if (fieldKey.includes("amount") || fieldKey.includes("Amount") || fieldKey.includes("tax") || fieldKey.includes("price"))
      return <span className="tabular-nums font-medium text-stone-700 dark:text-zinc-200">{n.toLocaleString("en-IN", { style: "currency", currency: "INR", maximumFractionDigits: 0 })}</span>;
    return <span className="tabular-nums">{n.toLocaleString()}</span>;
  }
  if (dataType === "datetime" || dataType === "date") {
    try { return <span>{new Date(String(value)).toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" })}</span>; }
    catch { return String(value); }
  }
  if (fieldKey === "instance_id") {
    return <span className="font-mono text-[11px] text-stone-400 dark:text-zinc-500 bg-stone-100 dark:bg-zinc-800 px-1.5 py-0.5 rounded-md">{String(value).slice(0, 8)}</span>;
  }
  return String(value);
}

// ---------------------------------------------------------------------------
// Status badge — Mahindra workflow states
// ---------------------------------------------------------------------------

const STATUS: Record<string, { bg: string; text: string; dot: string; darkBg: string; darkText: string; darkDot: string }> = {
  "Awaiting Scheduler Call": {
    bg: "bg-rose-50 border-rose-200",     text: "text-rose-700",     dot: "bg-rose-500 animate-pulse",
    darkBg: "dark:bg-rose-950/30 dark:border-rose-900",  darkText: "dark:text-rose-300", darkDot: "dark:bg-rose-400",
  },
  "Scheduled": {
    bg: "bg-amber-50 border-amber-200",   text: "text-amber-700",    dot: "bg-amber-500",
    darkBg: "dark:bg-amber-950/30 dark:border-amber-900", darkText: "dark:text-amber-300", darkDot: "dark:bg-amber-400",
  },
  "Awaiting Feedback Call": {
    bg: "bg-rose-50 border-rose-200",     text: "text-rose-700",     dot: "bg-rose-500 animate-pulse",
    darkBg: "dark:bg-rose-950/30 dark:border-rose-900",  darkText: "dark:text-rose-300", darkDot: "dark:bg-rose-400",
  },
  "Feedback Collected": {
    bg: "bg-emerald-50 border-emerald-200", text: "text-emerald-700", dot: "bg-emerald-500",
    darkBg: "dark:bg-emerald-950/30 dark:border-emerald-900", darkText: "dark:text-emerald-300", darkDot: "dark:bg-emerald-400",
  },
  "Scheduling Call Failed": {
    bg: "bg-red-50 border-red-200",       text: "text-red-700",      dot: "bg-red-500",
    darkBg: "dark:bg-red-950/30 dark:border-red-900",    darkText: "dark:text-red-300",  darkDot: "dark:bg-red-400",
  },
  "Feedback Call Failed": {
    bg: "bg-red-50 border-red-200",       text: "text-red-700",      dot: "bg-red-500",
    darkBg: "dark:bg-red-950/30 dark:border-red-900",    darkText: "dark:text-red-300",  darkDot: "dark:bg-red-400",
  },
  "End State": {
    bg: "bg-stone-100 border-stone-200",  text: "text-stone-600",    dot: "bg-stone-400",
    darkBg: "dark:bg-zinc-800 dark:border-zinc-700",     darkText: "dark:text-zinc-400", darkDot: "dark:bg-zinc-500",
  },
};

function StatusBadge({ value }: { value: string }) {
  const s = STATUS[value] ?? { bg: "bg-stone-100 border-stone-200", text: "text-stone-600", dot: "bg-stone-400", darkBg: "dark:bg-zinc-800 dark:border-zinc-700", darkText: "dark:text-zinc-400", darkDot: "dark:bg-zinc-500" };
  return (
    <span className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold border ${s.bg} ${s.text} ${s.darkBg} ${s.darkText}`}>
      <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${s.dot} ${s.darkDot}`} />
      {value}
    </span>
  );
}
