import { useMemo, useState } from "react";
import {
  Box,
  CircularProgress,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TableSortLabel,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { TableToolbar } from "./TableToolbar";
import { RowActions } from "./RowActions";
import { useColumnResize } from "./useColumnResize";
import { TablePaginationBar } from "../TablePaginationBar";

/**
 * <StandardTable>
 *
 * Tabla estándar del ERP. Ver src/components/_standards/StandardTable/README para API.
 * Soporta search/sort/pagination en modo client o server, acciones inline o menú,
 * resize de columnas persistente, y vista cards en mobile.
 */
export const StandardTable = ({
  data = [],
  loading = false,
  rowKey = "id",
  columns = [],
  actions = [],
  actionsMode = "auto",
  actionsLabel = "Acciones",
  search,
  filters,
  sort,
  pagination,
  mobileBreakpoint = 1100,
  cardRender,
  emptyState,
  toolbar,
  exportExcel,
  density = "comfortable",
  tableId,
  onRowClick,
  summary,
}) => {
  const theme = useTheme();
  const isMobile = useMediaQuery(`(max-width:${mobileBreakpoint}px)`);
  const { getWidth, onResizeStart } = useColumnResize(tableId, columns);

  // ── Búsqueda client-side ────────────────────────────────────────────
  const [internalSearch, setInternalSearch] = useState("");
  const searchValue = search?.value ?? internalSearch;
  const handleSearchChange = (v) => {
    if (search?.onChange) search.onChange(v);
    if (!search) setInternalSearch(v);
  };

  // ── Sort client-side ────────────────────────────────────────────────
  const [internalSort, setInternalSort] = useState(null);
  const sortValue = sort?.value ?? internalSort;
  const handleSort = (key) => {
    const next =
      sortValue?.key === key
        ? { key, dir: sortValue.dir === "asc" ? "desc" : "asc" }
        : { key, dir: "asc" };
    if (sort?.onChange) sort.onChange(next);
    if (!sort) setInternalSort(next);
  };

  // ── Datos procesados ─────────────────────────────────────────────────
  const processed = useMemo(() => {
    let rows = data;

    if (search?.mode !== "server" && searchValue?.trim()) {
      const q = searchValue.toLowerCase();
      const fields = search?.fields || columns.map((c) => c.key);
      rows = rows.filter((row) =>
        fields.some((f) => {
          const v = row[f];
          return v != null && String(v).toLowerCase().includes(q);
        }),
      );
    }

    if (sort?.mode !== "server" && sortValue?.key) {
      const col = columns.find((c) => c.key === sortValue.key);
      const getter = col?.sortValue || ((r) => r[sortValue.key]);
      rows = [...rows].sort((a, b) => {
        const va = getter(a);
        const vb = getter(b);
        if (va == null && vb == null) return 0;
        if (va == null) return 1;
        if (vb == null) return -1;
        if (typeof va === "number" && typeof vb === "number") {
          return sortValue.dir === "asc" ? va - vb : vb - va;
        }
        return sortValue.dir === "asc"
          ? String(va).localeCompare(String(vb))
          : String(vb).localeCompare(String(va));
      });
    }

    return rows;
  }, [data, search, searchValue, sort, sortValue, columns]);

  // ── Paginación client-side ──────────────────────────────────────────
  const pageMode = pagination?.mode ?? (pagination ? "server" : "client");
  const pageSize = pagination?.pageSize ?? 20;
  const [internalPage, setInternalPage] = useState(1);
  const page = pagination?.page ?? internalPage;
  const total = pagination?.total ?? processed.length;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const visible = useMemo(() => {
    if (pageMode === "server" || !pagination) return processed;
    const start = (page - 1) * pageSize;
    return processed.slice(start, start + pageSize);
  }, [processed, pageMode, pagination, page, pageSize]);

  const handlePageChange = (_e, newPage) => {
    if (pagination?.onPageChange) pagination.onPageChange(newPage);
    else setInternalPage(newPage);
  };

  // ── Render ───────────────────────────────────────────────────────────
  const padding = density === "compact" ? "6px 10px" : "10px 14px";

  const renderCell = (row, col) => {
    if (col.render) return col.render(row);
    const v = row[col.key];
    return v == null || v === "" ? "—" : String(v);
  };

  const renderActions = (row) =>
    actions.length > 0 ? (
      <RowActions row={row} actions={actions} mode={actionsMode} selectLabel={actionsLabel} />
    ) : null;

  return (
    <Box>
      {summary && <Box sx={{ mb: 2 }}>{summary}</Box>}

      <TableToolbar
        search={
          search
            ? { ...search, value: searchValue, onChange: handleSearchChange }
            : null
        }
        filters={filters}
        toolbar={toolbar}
        onExportExcel={exportExcel?.onClick}
      />

      {/* ── Desktop ── */}
      {!isMobile && (
        <TableContainer sx={{ borderRadius: 1, border: 1, borderColor: "divider" }}>
          <Table size={density === "compact" ? "small" : "medium"} sx={{ tableLayout: "fixed", width: "100%" }}>
            <TableHead>
              <TableRow>
                {columns.map((col) => {
                  const w = getWidth(col);
                  const wCss = typeof w === "number" ? `${w}px` : w;
                  const isSorted = sortValue?.key === col.key;
                  return (
                    <TableCell
                      key={col.key}
                      align={col.align || "left"}
                      sx={{
                        width: wCss,
                        minWidth: `${col.minWidth || 60}px`,
                        padding,
                        position: "relative",
                        fontWeight: 600,
                        textTransform: "uppercase",
                        fontSize: "0.72rem",
                        letterSpacing: 0.3,
                        userSelect: "none",
                        whiteSpace: "nowrap",
                        borderRight: 1,
                        borderColor: "divider",
                        "&:last-child": { borderRight: 0 },
                      }}
                    >
                      {col.sortable ? (
                        <TableSortLabel
                          active={isSorted}
                          direction={isSorted ? sortValue.dir : "asc"}
                          onClick={() => handleSort(col.key)}
                        >
                          {col.label}
                        </TableSortLabel>
                      ) : (
                        col.label
                      )}
                      {col.resizable && (
                        <Box
                          onMouseDown={(e) => {
                            e.preventDefault();
                            const th = e.currentTarget.parentElement;
                            onResizeStart(col.key, e.clientX, th.offsetWidth);
                          }}
                          sx={{
                            position: "absolute",
                            top: 0,
                            right: -4,
                            width: 8,
                            height: "100%",
                            cursor: "col-resize",
                            zIndex: 1,
                            "&::after": {
                              content: '""',
                              position: "absolute",
                              top: "25%",
                              left: "50%",
                              transform: "translateX(-50%)",
                              width: "2px",
                              height: "50%",
                              bgcolor: "transparent",
                              borderRadius: 1,
                              transition: "background-color 0.15s",
                            },
                            "&:hover::after": {
                              bgcolor: "primary.main",
                            },
                          }}
                        />
                      )}
                    </TableCell>
                  );
                })}
                {actions.length > 0 && (() => {
                  const actionsWidth = getWidth({ key: "__actions" });
                  return (
                    <TableCell
                      align="right"
                      sx={{
                        width: actionsWidth ? `${actionsWidth}px` : "1px",
                        minWidth: "80px",
                        padding,
                        position: "relative",
                        fontWeight: 600,
                        textTransform: "uppercase",
                        fontSize: "0.72rem",
                        whiteSpace: "nowrap",
                      }}
                    >
                      {actionsLabel}
                    </TableCell>
                  );
                })()}
              </TableRow>
            </TableHead>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={columns.length + (actions.length > 0 ? 1 : 0)} align="center" sx={{ py: 6 }}>
                    <CircularProgress size={28} />
                  </TableCell>
                </TableRow>
              ) : visible.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={columns.length + (actions.length > 0 ? 1 : 0)} sx={{ py: 6 }}>
                    {emptyState || (
                      <Typography variant="body2" sx={{ textAlign: "center", opacity: 0.6 }}>
                        Sin registros
                      </Typography>
                    )}
                  </TableCell>
                </TableRow>
              ) : (
                visible.map((row) => (
                  <TableRow
                    key={row[rowKey]}
                    hover
                    onClick={onRowClick ? () => onRowClick(row) : undefined}
                    sx={{ cursor: onRowClick ? "pointer" : "default" }}
                  >
                    {columns.map((col) => {
                      const mw = getWidth(col) || col.maxWidth;
                      const mwCss = typeof mw === "number" ? `${mw}px` : mw;
                      return (
                      <TableCell
                        key={col.key}
                        align={col.align || "left"}
                        sx={{
                          padding,
                          whiteSpace: col.wrap ? "normal" : "nowrap",
                          textOverflow: "ellipsis",
                          overflow: "hidden",
                          maxWidth: mwCss,
                        }}
                      >
                        {renderCell(row, col)}
                      </TableCell>
                      );
                    })}
                    {actions.length > 0 && (
                      <TableCell
                        align="right"
                        sx={{ padding, whiteSpace: "nowrap", width: "1px" }}
                        onClick={(e) => e.stopPropagation()}
                      >
                        {renderActions(row)}
                      </TableCell>
                    )}
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>
      )}

      {/* ── Mobile cards ── */}
      {isMobile && (
        <Stack spacing={1.5}>
          {loading ? (
            <Box sx={{ textAlign: "center", py: 4 }}>
              <CircularProgress size={28} />
            </Box>
          ) : visible.length === 0 ? (
            emptyState || (
              <Typography variant="body2" sx={{ textAlign: "center", py: 4, opacity: 0.6 }}>
                Sin registros
              </Typography>
            )
          ) : (
            visible.map((row) => (
              <Box
                key={row[rowKey]}
                onClick={onRowClick ? () => onRowClick(row) : undefined}
                sx={{
                  border: 1,
                  borderColor: "divider",
                  borderRadius: 1,
                  p: 1.5,
                  cursor: onRowClick ? "pointer" : "default",
                  "&:hover": onRowClick ? { bgcolor: "action.hover" } : undefined,
                }}
              >
                {cardRender ? (
                  cardRender(row)
                ) : (
                  <DefaultCard row={row} columns={columns} renderCell={renderCell} />
                )}
                {actions.length > 0 && (
                  <Box sx={{ mt: 1.5, display: "flex", justifyContent: "flex-end" }} onClick={(e) => e.stopPropagation()}>
                    {renderActions(row)}
                  </Box>
                )}
              </Box>
            ))
          )}
        </Stack>
      )}

      {/* ── Footer / Pagination (barra estándar unificada) ── */}
      {pagination && (
        <TablePaginationBar
          page={page}
          totalPages={totalPages}
          onPageChange={(newPage) => handlePageChange(null, newPage)}
          total={total}
          shown={visible.length}
          noun={pagination.noun || "registros"}
          rowsPerPage={pagination.onPageSizeChange ? pageSize : undefined}
          onRowsPerPageChange={pagination.onPageSizeChange}
          rowsPerPageOptions={pagination.pageSizeOptions}
        />
      )}
    </Box>
  );
};

const DefaultCard = ({ row, columns, renderCell }) => {
  const primary = columns.find((c) => c.primary);
  const chips = columns.filter((c) => c.chip && !c.hideOnMobile);
  const highlight = columns.find((c) => c.highlight && !c.hideOnMobile);
  const captions = columns.filter((c) => c.caption && !c.hideOnMobile);
  const others = columns.filter(
    (c) =>
      !c.primary &&
      !c.chip &&
      !c.highlight &&
      !c.caption &&
      !c.hideOnMobile,
  );

  return (
    <>
      {/* Fila 1: primary + chips de estado */}
      {(primary || chips.length > 0) && (
        <Box
          sx={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "flex-start",
            gap: 1,
            mb: 0.5,
          }}
        >
          {primary && (
            <Typography
              variant="body2"
              fontWeight={700}
              sx={{ fontFamily: primary.mono ? "monospace" : "inherit" }}
            >
              {renderCell(row, primary)}
            </Typography>
          )}
          {chips.length > 0 && (
            <Box sx={{ display: "flex", gap: 0.5, flexWrap: "wrap", justifyContent: "flex-end" }}>
              {chips.map((col) => (
                <Box key={col.key}>{renderCell(row, col)}</Box>
              ))}
            </Box>
          )}
        </Box>
      )}

      {/* Captions debajo del primary (nombre cliente, ruc, etc.) */}
      {captions.map((col) => (
        <Typography
          key={col.key}
          variant={col.size === "sm" ? "caption" : "body2"}
          color={col.size === "sm" ? "text.secondary" : "text.primary"}
          noWrap
          sx={{ display: "block" }}
        >
          {renderCell(row, col)}
        </Typography>
      ))}

      {/* Highlight (total/monto) destacado abajo */}
      {highlight && (
        <Typography variant="body1" fontWeight={700} color="primary.main" sx={{ mt: 0.75 }}>
          {renderCell(row, highlight)}
        </Typography>
      )}

      {/* Otras columnas como label: value */}
      {others.length > 0 && (
        <Box sx={{ display: "flex", flexWrap: "wrap", rowGap: 0.5, columnGap: 1.5, mt: 0.5 }}>
          {others.map((col) => (
            <Box key={col.key} sx={{ minWidth: 0 }}>
              <Typography variant="caption" sx={{ opacity: 0.6, mr: 0.5 }}>
                {col.label}:
              </Typography>
              <Typography variant="body2" component="span">
                {renderCell(row, col)}
              </Typography>
            </Box>
          ))}
        </Box>
      )}
    </>
  );
};
