import React, { useEffect, useState, useRef } from 'react';
import { KanbanComponent } from '@syncfusion/ej2-react-kanban';
import { fetchClients, updateClientGroup } from './apiClients';
import { fetchGroups, createGroup, deleteGroup, renameGroup } from './apiGroups';
import type { Client } from './apiClients';
import type { KanbanComponent as KanbanComponentType } from '@syncfusion/ej2-react-kanban';
import { DialogComponent } from '@syncfusion/ej2-react-popups';
import { useToast } from './components/ToastProvider';
import { L10n } from '@syncfusion/ej2-base';

interface KanbanClient extends Client {
  Id: string;
  Status: string; // Raumgruppe (Gruppenname)
  Summary: string; // Anzeigename
}

interface Group {
  id: number;
  name: string;
  // weitere Felder möglich
}

interface KanbanDragEventArgs {
  element: HTMLElement | HTMLElement[];
  data: KanbanClient | KanbanClient[];
  event?: { event?: MouseEvent };
  [key: string]: unknown;
}

interface KanbanComponentWithClear extends KanbanComponentType {
  clearSelection: () => void;
}

const de = {
  title: 'Gruppen',
  newGroup: 'Neue Raumgruppe',
  renameGroup: 'Gruppe umbenennen',
  deleteGroup: 'Gruppe löschen',
  add: 'Hinzufügen',
  cancel: 'Abbrechen',
  rename: 'Umbenennen',
  confirmDelete: 'Löschbestätigung',
  reallyDelete: (name: string) => `Möchten Sie die Gruppe <b>${name}</b> wirklich löschen?`,
  clientsMoved: 'Alle Clients werden in "Nicht zugeordnet" verschoben.',
  groupCreated: 'Gruppe angelegt',
  groupDeleted: 'Gruppe gelöscht. Clients in "Nicht zugeordnet" verschoben',
  groupRenamed: 'Gruppenname geändert',
  selectGroup: 'Gruppe wählen',
  newName: 'Neuer Name',
  warning: 'Achtung:',
  yesDelete: 'Ja, löschen',
};

L10n.load({
  de: {
    kanban: {
      items: 'Clients',
      addTitle: 'Neue Karte hinzufügen',
      editTitle: 'Karte bearbeiten',
      deleteTitle: 'Karte löschen',
      edit: 'Bearbeiten',
      delete: 'Löschen',
      save: 'Speichern',
      cancel: 'Abbrechen',
      yes: 'Ja',
      no: 'Nein',
      noCard: 'Keine Clients vorhanden',
    },
  },
});

const Infoscreen_groups: React.FC = () => {
  const toast = useToast();
  const [clients, setClients] = useState<KanbanClient[]>([]);
  const [groups, setGroups] = useState<{ keyField: string; headerText: string }[]>([]);
  const [showDialog, setShowDialog] = useState(false);
  const [newGroupName, setNewGroupName] = useState('');
  const [draggedCard, setDraggedCard] = useState<{ id: string; fromColumn: string } | null>(null);
  const [renameDialog, setRenameDialog] = useState<{
    open: boolean;
    oldName: string;
    newName: string;
  }>({ open: false, oldName: '', newName: '' });
  const [deleteDialog, setDeleteDialog] = useState<{ open: boolean; groupName: string }>({
    open: false,
    groupName: '',
  });
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const kanbanRef = useRef<KanbanComponentType | null>(null); // Ref für Kanban

  // Lade Gruppen und Clients
  useEffect(() => {
    let groupMap: Record<number, string> = {};
    fetchGroups().then((groupData: Group[]) => {
      const kanbanGroups = groupData.map(g => ({
        keyField: g.name,
        headerText: g.name,
        id: g.id,
      }));
      setGroups(kanbanGroups);

      groupMap = Object.fromEntries(groupData.map(g => [g.id, g.name]));

      fetchClients().then(data => {
        setClients(
          data.map((c, i) => ({
            ...c,
            Id: c.uuid,
            Status: groupMap[c.group_id] || 'Nicht zugeordnet',
            Summary: c.location || `Client ${i + 1}`,
          }))
        );
      });
    });
  }, []);

  // Neue Gruppe anlegen (persistiert per API)
  const handleAddGroup = async () => {
    if (!newGroupName.trim()) return;
    try {
      const newGroup = await createGroup(newGroupName);
      toast.show({
        content: de.groupCreated,
        cssClass: 'e-toast-success',
        timeOut: 5000,
        showCloseButton: false,
      });
      setGroups([...groups, { keyField: newGroup.name, headerText: newGroup.name }]);
      setNewGroupName('');
      setShowDialog(false);
    } catch (err) {
      toast.show({
        content: (err as Error).message,
        cssClass: 'e-toast-danger',
        timeOut: 0,
        showCloseButton: true,
      });
    }
  };

  // Löschen einer Gruppe
  const handleDeleteGroup = async (groupName: string) => {
    try {
      // Clients der Gruppe in "Nicht zugeordnet" verschieben
      const groupClients = clients.filter(c => c.Status === groupName);
      if (groupClients.length > 0) {
        await updateClientGroup(
          groupClients.map(c => c.Id),
          'Nicht zugeordnet'
        );
      }
      await deleteGroup(groupName);
      toast.show({
        content: de.groupDeleted,
        cssClass: 'e-toast-success',
        timeOut: 5000,
        showCloseButton: false,
      });
      // Gruppen und Clients neu laden
      const groupData = await fetchGroups();
      const groupMap = Object.fromEntries(groupData.map((g: Group) => [g.id, g.name]));
      setGroups(groupData.map((g: Group) => ({ keyField: g.name, headerText: g.name, id: g.id })));
      const data = await fetchClients();
      setClients(
        data.map((c, i) => ({
          ...c,
          Id: c.uuid,
          Status: groupMap[c.group_id] || 'Nicht zugeordnet',
          Summary: c.location || `Client ${i + 1}`,
        }))
      );
    } catch (err) {
      toast.show({
        content: (err as Error).message,
        cssClass: 'e-toast-danger',
        timeOut: 0,
        showCloseButton: true,
      });
    }
    setDeleteDialog({ open: false, groupName: '' });
  };

  // Umbenennen einer Gruppe
  const handleRenameGroup = async () => {
    try {
      await renameGroup(renameDialog.oldName, renameDialog.newName);
      toast.show({
        content: de.groupRenamed,
        cssClass: 'e-toast-success',
        timeOut: 5000,
        showCloseButton: false,
      });
      // Gruppen und Clients neu laden
      const groupData = await fetchGroups();
      const groupMap = Object.fromEntries(groupData.map((g: Group) => [g.id, g.name]));
      setGroups(groupData.map((g: Group) => ({ keyField: g.name, headerText: g.name, id: g.id })));
      const data = await fetchClients();
      setClients(
        data.map((c, i) => ({
          ...c,
          Id: c.uuid,
          Status: groupMap[c.group_id] || 'Nicht zugeordnet',
          Summary: c.location || `Client ${i + 1}`,
        }))
      );
    } catch (err) {
      toast.show({
        content: (err as Error).message,
        cssClass: 'e-toast-danger',
        timeOut: 0,
        showCloseButton: true,
      });
    }
    setRenameDialog({ open: false, oldName: '', newName: '' });
  };

  const handleDragStart = (args: KanbanDragEventArgs) => {
    const element = Array.isArray(args.element) ? args.element[0] : args.element;
    const cardId = element.getAttribute('data-id');
    const fromColumn = element.getAttribute('data-key');
    setDraggedCard({ id: cardId || '', fromColumn: fromColumn || '' });
  };

  const handleCardDrop = async (args: KanbanDragEventArgs) => {
    if (!draggedCard) return;

    const mouseEvent = args.event?.event;
    let targetGroupName = '';

    if (mouseEvent && mouseEvent.clientX && mouseEvent.clientY) {
      const targetElement = document.elementFromPoint(mouseEvent.clientX, mouseEvent.clientY);
      const kanbanColumn =
        targetElement?.closest('[data-key]') || targetElement?.closest('.e-content-row');
      if (kanbanColumn) {
        const columnKey = kanbanColumn.getAttribute('data-key');
        if (columnKey) {
          targetGroupName = columnKey;
        } else {
          const headerElement = kanbanColumn.querySelector('.e-header-text');
          targetGroupName = headerElement?.textContent?.trim() || '';
        }
      }
    }

    // Fallback
    if (!targetGroupName) {
      const targetElement = Array.isArray(args.element) ? args.element[0] : args.element;
      const cardWrapper = targetElement.closest('.e-card-wrapper');
      const contentRow = cardWrapper?.closest('.e-content-row');
      const headerText = contentRow?.querySelector('.e-header-text');
      targetGroupName = headerText?.textContent?.trim() || '';
    }

    if (!targetGroupName || targetGroupName === draggedCard.fromColumn) {
      setDraggedCard(null);
      return;
    }

    const dropped = Array.isArray(args.data) ? args.data : [args.data];
    const clientIds = dropped.map((card: KanbanClient) => card.Id);

    try {
      await updateClientGroup(clientIds, targetGroupName);
      fetchGroups().then((groupData: Group[]) => {
        const groupMap = Object.fromEntries(groupData.map(g => [g.id, g.name]));
        setGroups(
          groupData.map(g => ({
            keyField: g.name,
            headerText: g.name,
            id: g.id,
          }))
        );
        fetchClients().then(data => {
          setClients(
            data.map((c, i) => ({
              ...c,
              Id: c.uuid,
              Status: groupMap[c.group_id] || 'Nicht zugeordnet',
              Summary: c.location || `Client ${i + 1}`,
            }))
          );
          // Nach dem Laden: Karten deselektieren
          setTimeout(() => {
            (kanbanRef.current as KanbanComponentWithClear)?.clearSelection();
            setTimeout(() => {
              (kanbanRef.current as KanbanComponentWithClear)?.clearSelection();
            }, 100);
          }, 50);
        });
      });
    } catch {
      alert('Fehler beim Aktualisieren der Clients');
    }
    setDraggedCard(null);
  };

  // Spalten-Array ohne Header-Buttons/Template
  const kanbanColumns = groups.map(group => ({
    keyField: group.keyField,
    headerText: group.headerText,
  }));

  return (
    <div id="dialog-target">
      <h2 className="text-xl font-bold mb-4">{de.title}</h2>
      <div className="flex gap-2 mb-4">
        <button
          className="px-4 py-2 bg-blue-500 text-white rounded"
          onClick={() => setShowDialog(true)}
        >
          {de.newGroup}
        </button>
        <button
          className="px-4 py-2 bg-yellow-500 text-white rounded"
          onClick={() => setRenameDialog({ open: true, oldName: '', newName: '' })}
        >
          {de.renameGroup}
        </button>
        <button
          className="px-4 py-2 bg-red-500 text-white rounded"
          onClick={() => setDeleteDialog({ open: true, groupName: '' })}
        >
          {de.deleteGroup}
        </button>
      </div>
      <KanbanComponent
        locale="de"
        id="kanban"
        keyField="Status"
        dataSource={clients}
        cardSettings={{
          headerField: 'Summary',
          selectionType: 'Multiple',
        }}
        allowDragAndDrop={true}
        dragStart={handleDragStart}
        dragStop={handleCardDrop}
        ref={kanbanRef}
        columns={kanbanColumns}
      />
      {showDialog && (
        <div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center">
          <div className="bg-white p-6 rounded shadow">
            <h3 className="mb-2 font-bold">{de.newGroup}</h3>
            <input
              className="border p-2 mb-2 w-full"
              value={newGroupName}
              onChange={e => setNewGroupName(e.target.value)}
              placeholder="Raumname"
            />
            <div className="flex gap-2">
              <button className="bg-blue-500 text-white px-4 py-2 rounded" onClick={handleAddGroup}>
                {de.add}
              </button>
              <button
                className="bg-gray-300 px-4 py-2 rounded"
                onClick={() => setShowDialog(false)}
              >
                {de.cancel}
              </button>
            </div>
          </div>
        </div>
      )}
      {renameDialog.open && (
        <div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center">
          <div className="bg-white p-6 rounded shadow">
            <h3 className="mb-2 font-bold">{de.renameGroup}</h3>
            <select
              className="border p-2 mb-2 w-full"
              value={renameDialog.oldName}
              onChange={e =>
                setRenameDialog({
                  ...renameDialog,
                  oldName: e.target.value,
                  newName: e.target.value,
                })
              }
            >
              <option value="">{de.selectGroup}</option>
              {groups
                .filter(g => g.headerText !== 'Nicht zugeordnet')
                .map(g => (
                  <option key={g.keyField} value={g.headerText}>
                    {g.headerText}
                  </option>
                ))}
            </select>
            <input
              className="border p-2 mb-2 w-full"
              value={renameDialog.newName}
              onChange={e => setRenameDialog({ ...renameDialog, newName: e.target.value })}
              placeholder={de.newName}
            />
            <div className="flex gap-2">
              <button
                className="bg-blue-500 text-white px-4 py-2 rounded"
                onClick={handleRenameGroup}
                disabled={!renameDialog.oldName || !renameDialog.newName}
              >
                {de.rename}
              </button>
              <button
                className="bg-gray-300 px-4 py-2 rounded"
                onClick={() => setRenameDialog({ open: false, oldName: '', newName: '' })}
              >
                {de.cancel}
              </button>
            </div>
          </div>
        </div>
      )}
      {deleteDialog.open && (
        <div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center">
          <div className="bg-white p-6 rounded shadow">
            <h3 className="mb-2 font-bold">{de.deleteGroup}</h3>
            <select
              className="border p-2 mb-2 w-full"
              value={deleteDialog.groupName}
              onChange={e => setDeleteDialog({ ...deleteDialog, groupName: e.target.value })}
            >
              <option value="">{de.selectGroup}</option>
              {groups
                .filter(g => g.headerText !== 'Nicht zugeordnet')
                .map(g => (
                  <option key={g.keyField} value={g.headerText}>
                    {g.headerText}
                  </option>
                ))}
            </select>
            <p>{de.clientsMoved}</p>
            {deleteDialog.groupName && (
              <div className="bg-yellow-100 text-yellow-800 p-2 rounded mb-2 text-sm">
                <strong>{de.warning}</strong> Möchten Sie die Gruppe <b>{deleteDialog.groupName}</b>{' '}
                wirklich löschen?
              </div>
            )}
            <div className="flex gap-2 mt-2">
              <button
                className="bg-red-500 text-white px-4 py-2 rounded"
                onClick={() => setShowDeleteConfirm(true)}
                disabled={!deleteDialog.groupName}
              >
                {de.deleteGroup}
              </button>
              <button
                className="bg-gray-300 px-4 py-2 rounded"
                onClick={() => setDeleteDialog({ open: false, groupName: '' })}
              >
                {de.cancel}
              </button>
            </div>
          </div>
          {showDeleteConfirm && deleteDialog.groupName && (
            <DialogComponent
              width="350px"
              header={de.confirmDelete}
              visible={showDeleteConfirm}
              close={() => setShowDeleteConfirm(false)}
              footerTemplate={() => (
                <div className="flex gap-2 justify-end">
                  <button
                    className="bg-red-500 text-white px-4 py-2 rounded"
                    onClick={() => {
                      handleDeleteGroup(deleteDialog.groupName);
                      setShowDeleteConfirm(false);
                    }}
                  >
                    {de.yesDelete}
                  </button>
                  <button
                    className="bg-gray-300 px-4 py-2 rounded"
                    onClick={() => {
                      setShowDeleteConfirm(false);
                      setDeleteDialog({ open: false, groupName: '' });
                    }}
                  >
                    {de.cancel}
                  </button>
                </div>
              )}
            >
              <div>
                Möchten Sie die Gruppe <b>{deleteDialog.groupName}</b> wirklich löschen?
                <br />
                <span className="text-sm text-gray-500">{de.clientsMoved}</span>
              </div>
            </DialogComponent>
          )}
        </div>
      )}
    </div>
  );
};

export default Infoscreen_groups;
