﻿// react
import React, { useState, useEffect, useCallback } from "react";
// application
import { IModel } from "~/admin/interfaces/vehicle";
import { SortableTableHeader } from "~/admin/components/table/SortableTableHeader";

type Grouped = {
  brandID: number;
  brandName: string;
  items: IModel[];
};

/** Marca con su orden canónico (igual que la página de Marcas). */
export interface BrandOrderItem {
  id: number;
  sort_position?: number;
  position?: number;
}

interface Props {
  models: IModel[];
  /** Orden canónico de marcas: los grupos (marcas) SIEMPRE se muestran en este orden. */
  brandOrder?: BrandOrderItem[];
  onEdit: (model: IModel) => void;
  onDelete: (id: number) => void;
  onReorder: (models: IModel[]) => Promise<void>;
}

export const ModelList = ({ models, brandOrder = [], onEdit, onDelete, onReorder }: Props) => {
  const [ordered, setOrdered] = useState<Grouped[]>([]);
  const [draggedId, setDraggedId] = useState<number | null>(null);
  const [dragOverId, setDragOverId] = useState<number | null>(null);

  const buildGroups = useCallback(
    (list: IModel[]): Grouped[] => {
      const map = new Map<number, Grouped>();
      list.forEach((m) => {
        const brandID = m.vehicle_brandID;
        if (!map.has(brandID)) {
          map.set(brandID, {
            brandID,
            brandName: m.brand_name || `Marca ${brandID}`,
            items: [],
          });
        }
        map.get(brandID)!.items.push(m);
      });
      const groups = Array.from(map.values());

      // Los GRUPOS (marcas) se ordenan por el orden canónico de marcas,
      // NO por el orden global de modelos (que el backend ordena por
      // sort_position + nombre y puede "bailar" las marcas al arrastrar).
      if (brandOrder.length > 0) {
        const index = new Map<number, number>();
        brandOrder.forEach((b, i) => index.set(b.id, i));
        groups.sort((a, b) => {
          const ia = index.get(a.brandID) ?? Number.MAX_SAFE_INTEGER;
          const ib = index.get(b.brandID) ?? Number.MAX_SAFE_INTEGER;
          return ia - ib;
        });
      }

      return groups;
    },
    [brandOrder],
  );

  useEffect(() => {
    setOrdered(buildGroups(models));
  }, [models, buildGroups]);

  const handleDragStart = (e: React.DragEvent<HTMLTableRowElement>, model: IModel) => {
    setDraggedId(model.id);
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/plain", String(model.id));
    e.dataTransfer.setData("brand", String(model.vehicle_brandID));
  };

  const handleDragOver = (e: React.DragEvent<HTMLTableRowElement>, model: IModel) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
    setDragOverId(model.id);
  };

  const handleDrop = useCallback(
    async (e: React.DragEvent<HTMLTableRowElement>, target: IModel) => {
      e.preventDefault();
      if (draggedId == null || target.id === draggedId) return;

      const sourceBrand = e.dataTransfer.getData("brand");
      if (sourceBrand && Number(sourceBrand) !== target.vehicle_brandID) {
        setDragOverId(null);
        setDraggedId(null);
        return;
      }

      const fromGroup = ordered.findIndex((g) => g.items.some((m) => m.id === draggedId));
      const toGroup = ordered.findIndex((g) => g.items.some((m) => m.id === target.id));
      if (fromGroup === -1 || toGroup === -1 || fromGroup !== toGroup) return;

      const group = ordered[fromGroup];
      const fromIdx = group.items.findIndex((m) => m.id === draggedId);
      const toIdx = group.items.findIndex((m) => m.id === target.id);
      if (fromIdx === -1 || toIdx === -1 || fromIdx === toIdx) return;

      const newItems = [...group.items];
      const [moved] = newItems.splice(fromIdx, 1);
      newItems.splice(toIdx, 0, moved);

      const newGroups = ordered.map((g) =>
        g.brandID === group.brandID ? { ...g, items: newItems } : g,
      );
      setOrdered(newGroups);
      setDragOverId(null);
      setDraggedId(null);

      await onReorder(newItems);
    },
    [draggedId, ordered, onReorder],
  );

  const handleDragEnd = () => {
    setDraggedId(null);
    setDragOverId(null);
  };

  if (models.length === 0) {
    return (
      <div className="card">
        <div className="card-body text-center py-5">
          <i className="fas fa-car fa-3x text-muted mb-3" />
          <p className="text-muted">No hay modelos registrados</p>
        </div>
      </div>
    );
  }

  return (
    <div className="card">
      <div className="card-body">
        <div className="table-responsive">
          <table className="table table-hover">
            <thead>
              <tr>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                  className="text-center"
                >
                  Ordenar
                </SortableTableHeader>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                  className="text-center"
                >
                  Nombre
                </SortableTableHeader>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                  className="text-center"
                >
                  Cant. Productos
                </SortableTableHeader>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                  className="text-center"
                >
                  Imagen
                </SortableTableHeader>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                  className="text-center"
                >
                  Estado
                </SortableTableHeader>
                <SortableTableHeader
                  sortKey=""
                  currentSortKey={null}
                  sortDirection={null}
                  onSort={() => {}}
                  sortable={false}
                >
                  Acciones
                </SortableTableHeader>
              </tr>
            </thead>
            <tbody>
              {ordered.map((group) => (
                <React.Fragment key={group.brandID}>
                  <tr className="table-secondary">
                    <td colSpan={6} className="font-weight-bold text-uppercase">
                      <i className="fas fa-tag mr-2" />
                      {group.brandName}
                      <span className="badge badge-light ml-2">
                        {group.items.length} modelo{group.items.length !== 1 ? "s" : ""}
                      </span>
                    </td>
                  </tr>
                  {group.items.map((model) => (
                    <tr
                      key={model.id}
                      draggable
                      data-id={model.id}
                      onDragStart={(e) => handleDragStart(e, model)}
                      onDragOver={(e) => handleDragOver(e, model)}
                      onDrop={(e) => void handleDrop(e, model)}
                      onDragEnd={handleDragEnd}
                      className={dragOverId === model.id ? "table-row-drag-over" : undefined}
                    >
                      <td className="text-center align-middle" style={{ width: 40 }}>
                        <i
                          className="fas fa-grip-vertical text-muted"
                          style={{ cursor: draggedId === model.id ? "grabbing" : "grab", fontSize: 14 }}
                          aria-hidden="true"
                        />
                      </td>
                      <td className="align-middle">{model.name}</td>
                      <td className="text-center align-middle">{model.products_count ?? 0}</td>
                      <td className="text-center align-middle">
                        {model.imageUrl ? (
                          <img
                            src={model.imageUrl}
                            alt=""
                            loading="lazy"
                            decoding="async"
                            className="model-list__thumb d-block mx-auto"
                            style={{ width: 40, height: 40, objectFit: "cover", borderRadius: 4 }}
                          />
                        ) : (
                          <span className="text-muted">—</span>
                        )}
                      </td>
                      <td className="text-center align-middle">
                        {model.status === false || model.status === 0 ? "Inactivo" : "Activo"}
                      </td>
                      <td>
                        <button
                          type="button"
                          className="btn btn-sm btn-primary mr-2"
                          onClick={() => onEdit(model)}
                        >
                          <i className="fas fa-edit" />
                        </button>
                        <button
                          type="button"
                          className="btn btn-sm btn-danger"
                          onClick={() => model.id && onDelete(model.id)}
                        >
                          <i className="fas fa-trash" />
                        </button>
                      </td>
                    </tr>
                  ))}
                </React.Fragment>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      <style jsx>{`
        tr.table-row-drag-over td {
          background-color: #e9ecef !important;
        }
      `}</style>
    </div>
  );
};
