import React, { useState, useEffect, useRef } from "react";
import { Modal } from "../Modal";
import { Select } from "../Select";
import { Button } from "../Button";
import { Badge } from "../Badge";
import { Tooltip } from "../Tooltip";
import { ReactComponent as SaveViewDeleteIcon } from "../../assets/saveViewDeleteIcon.svg";
import DragIndicatorIcon from "@mui/icons-material/DragIndicator";
import { ReactComponent as AddOutlinedIcon } from "../../assets/plus.svg";

const SORT_ORDER_OPTIONS_TEXT = [
  { label: "Ascending (A To Z)", value: "asc" },
  { label: "Descending (Z To A)", value: "desc" },
];

const SORT_ORDER_OPTIONS_NUMBER = [
  { label: "Smallest to largest", value: "asc" },
  { label: "Largest to smallest", value: "desc" },
];

function getSortOrderOptionsByFilter(filterType) {
  if (filterType === "agNumberColumnFilter") {
    return SORT_ORDER_OPTIONS_NUMBER;
  }
  if (
    filterType === "agTextColumnFilter"
  ) {
    return SORT_ORDER_OPTIONS_TEXT;
  }
  return SORT_ORDER_OPTIONS_TEXT;
}

let nextId = 1;
const generateId = () => `sort-row-${nextId++}`;

function buildColumnOptions(colDefs) {
  const options = [];
  const collect = (cols) => {
    if (!Array.isArray(cols)) return;
    cols.forEach((col) => {
      if (col.children) {
        collect(col.children);
      } else if (col.field && col.sortable) {
        options.push({
          label: col.headerName || col.field,
          value: col.field,
          filter: col.filter,
        });
      }
    });
  };
  collect(colDefs);
  return options;
}

function makeEmptyRow() {
  return { id: generateId(), colId: null, order: "null" };
}

function SortRow({
  row,
  index,
  availableColumnOptions,
  selectedColumnOption,
  selectedOrderOption,
  selectedColumnFilter,
  onColumnChange,
  onOrderChange,
  onDelete,
  dragHandlers,
  rowsCount,
}) {
  const [columnIsOpen, setColumnIsOpen] = useState(false);
  const [orderIsOpen, setOrderIsOpen] = useState(false);
  const [columnCurrentOptions, setColumnCurrentOptions] = useState(
    availableColumnOptions
  );
  const [orderCurrentOptions, setOrderCurrentOptions] = useState(
    getSortOrderOptionsByFilter(selectedColumnFilter)
  );

  // Keep currentOptions in sync if availableColumnOptions changes (eg. another row picks a column)
  useEffect(() => {
    setColumnCurrentOptions(availableColumnOptions);
  }, [availableColumnOptions]);

  useEffect(() => {
    setOrderCurrentOptions(getSortOrderOptionsByFilter(selectedColumnFilter));
  }, [selectedColumnFilter]);

  return (
    <div
      className="advance-sort-row"
      draggable
      onDragStart={() => dragHandlers.onDragStart(index)}
      onDragEnter={() => dragHandlers.onDragEnter(index)}
      onDragEnd={dragHandlers.onDragEnd}
      onDragOver={(e) => e.preventDefault()}
    >
      <div className="advance-sort-row-content">
        <DragIndicatorIcon className="advance-sort-drag-indicator" />
        <div className="advance-sort-field-group">
          <Select
            label="Column"
            placeholder="Select column"
            minWidth="210px"
            withPortal
            isWithSearch
            initialOptions={availableColumnOptions}
            currentOptions={columnCurrentOptions}
            setCurrentOptions={setColumnCurrentOptions}
            selectedOptions={selectedColumnOption}
            setSelectedOptions={() => {}}
            isOpen={columnIsOpen}
            setIsOpen={setColumnIsOpen}
            handleChange={(val) => onColumnChange(index, val)}
          />
          <Select
            label="Sorting Order"
            placeholder="Select sorting order"
            minWidth="210px"
            withPortal
            initialOptions={getSortOrderOptionsByFilter(selectedColumnFilter)}
            currentOptions={orderCurrentOptions}
            setCurrentOptions={setOrderCurrentOptions}
            selectedOptions={selectedOrderOption}
            setSelectedOptions={() => {}}
            isOpen={orderIsOpen}
            setIsOpen={setOrderIsOpen}
            handleChange={(val) => onOrderChange(index, val)}
          />
        </div>
      </div>

      <div className="advance-sort-priority-group">
        <Badge
          color="default"
          label={`Priority ${index + 1}`}
          size="default"
          variant="filled"
          sx={{
            background: "#F1F3FE !important",
            "& .MuiChip-label": {
              color: "#4259EE !important",
            },
          }}
        />
        <div className="divider-line" />
        <Tooltip title="Delete" variant="tertiary">
          <span style={{ display: "inline-block" }}>
            <Button
              variant="secondary"
              type="destructive"
              size="medium"
              onClick={() => onDelete(index)}
              icon={<SaveViewDeleteIcon />}
              disabled={rowsCount === 1}
            />
          </span>
        </Tooltip>
      </div>
    </div>
  );
}

export default function AdvanceSortModal({
  open,
  onClose,
  colDefs = [],
  sortState = [],
  onApply,
}) {
  const [rows, setRows] = useState([makeEmptyRow()]);
  const dragIndexRef = useRef(null);
  const dragOverIndexRef = useRef(null);

  const columnOptions = buildColumnOptions(colDefs);

  useEffect(() => {
    if (!open) return;
    if (sortState && sortState.length > 0) {
      setRows(
        sortState.map((s) => ({
          id: generateId(),
          colId: s.colId,
          order: s.sort || "asc",
        }))
      );
    } else {
      setRows([makeEmptyRow()]);
    }
  }, [open]);

  const handleColumnChange = (index, option) => {
    setRows((prev) =>
      prev.map((row, i) =>
        i === index ? { ...row, colId: option ? option.value : null } : row
      )
    );
  };

  const handleOrderChange = (index, option) => {
    setRows((prev) =>
      prev.map((row, i) =>
        i === index ? { ...row, order: option ? option.value : "asc" } : row
      )
    );
  };

  const handleDeleteRow = (index) => {
    setRows((prev) => {
      const next = prev.filter((_, i) => i !== index);
      return next.length === 0 ? [makeEmptyRow()] : next;
    });
  };

  const handleAddLevel = () => {
    setRows((prev) => [...prev, makeEmptyRow()]);
  };

  const handleClearValues = () => {
    setRows((prev) =>
      prev.map((row, i) =>
        ({ ...row, order: null })
      )
    );
  };

  const handleClearAll = () => {
    setRows([makeEmptyRow()]);
  };

  const handleApply = () => {
    const validRows = rows.filter((r) => r.colId);
    onApply(validRows);
  };

  const onDragStart = (index) => {
    dragIndexRef.current = index;
  };
  const onDragEnter = (index) => {
    dragOverIndexRef.current = index;
  };
  const onDragEnd = () => {
    const from = dragIndexRef.current;
    const to = dragOverIndexRef.current;
    if (from === null || to === null || from === to) return;
    setRows((prev) => {
      const next = [...prev];
      const [removed] = next.splice(from, 1);
      next.splice(to, 0, removed);
      return next;
    });
    dragIndexRef.current = null;
    dragOverIndexRef.current = null;
  };

  const getSelectedColumnOption = (colId) =>
    columnOptions.find((o) => o.value === colId) || null;

  const getSelectedOrderOption = (order, colId) => {
    const filterType = getSelectedColumnOption(colId)?.filter;
    return (
      getSortOrderOptionsByFilter(filterType).find((o) => o.value === order) ||
      null
    );
  };

  const usedColIds = rows.map((r) => r.colId).filter(Boolean);

  const getAvailableColumnOptionsForRow = (rowColId) =>
    columnOptions.filter(
      (opt) => opt.value === rowColId || !usedColIds.includes(opt.value)
    );

  return (
    <Modal
      open={open}
      onClose={onClose}
      title="Advance Sort"
      size="medium"
      primaryButtonLabel="Apply"
      secondaryButtonLabel="Cancel"
      onPrimaryButtonClick={handleApply}
      onSecondaryButtonClick={onClose}
      className="advance-sort-modal"
    >
      <div className="advance-sort-modal-body">
        <div className="advance-sort-section-header">
          <span className="advance-sort-section-title">Column sort</span>
          <Button onClick={handleClearAll} variant="url">
            Clear All
          </Button>
        </div>

        <div className="advance-sort-rows">
          {rows.map((row, index) => (
            <SortRow
              key={row.id}
              row={row}
              rowsCount={rows.length}
              index={index}
              availableColumnOptions={getAvailableColumnOptionsForRow(row.colId)}
              selectedColumnOption={getSelectedColumnOption(row.colId)}
              selectedOrderOption={getSelectedOrderOption(row.order, row.colId)}
              selectedColumnFilter={getSelectedColumnOption(row.colId)?.filter}
              onColumnChange={handleColumnChange}
              onOrderChange={handleOrderChange}
              onDelete={handleDeleteRow}
              dragHandlers={{ onDragStart, onDragEnter, onDragEnd }}
            />
          ))}
        </div>

        <div className="advance-sort-footer-actions">
          <Button variant="secondary" onClick={handleClearValues}>
            Clear Values
          </Button>
          <Button
            variant="tertiary"
            onClick={handleAddLevel}
            icon={<AddOutlinedIcon />}
            className="advance-sort-add-level-button"
            disabled={columnOptions.length === rows.length}
          >
            Add Level
          </Button>
        </div>
      </div>
    </Modal>
  );
}
