import { Fragment, useCallback, useEffect, useState } from "react";
import { Plus, Save, Trash2, Info, ArrowUp, ArrowDown } from "lucide-react";
import OmsorgButton from "../../components/ui/OmsorgButton";
import { useAuth } from "../../app/AuthContext";
import { invalidateValueListCache } from "../../app/useValueListItems";

const ORDER_STATUS_KEY = "OrderStatus";
const CRM_STATUS_KEY = "CrmStatus";
const QUALIFICATION_KEY = "Qualification";

export default function StatusManagementPanel() {
  const { hasPermission } = useAuth();
  const canCreate = hasPermission("Configuration", "Create");
  const canEdit = hasPermission("Configuration", "Edit");

  const [lists, setLists] = useState([]);
  const [selectedKey, setSelectedKey] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  const loadLists = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    const result = await window.omsorg.valueLists.list();
    if (result.ok) {
      const data = result.data ?? [];
      setLists(data);
      setSelectedKey((current) => current ?? data[0]?.key ?? null);
    } else {
      setError("Auswahllisten konnten nicht geladen werden.");
    }
    setIsLoading(false);
  }, []);

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

  const selectedList = lists.find((list) => list.key === selectedKey);

  return (
    <div className="settings-roles-panel">
      <div className="settings-panel-heading">
        <h4>Status-Verwaltung</h4>
      </div>

      {isLoading && <p>Lädt...</p>}
      {error && <p className="login-error">{error}</p>}

      {!isLoading && !error && (
        <div className="settings-roles-layout">
          <div className="settings-roles-list">
            <ul>
              {lists.map((list) => (
                <li key={list.key}>
                  <button
                    type="button"
                    className={
                      list.key === selectedKey ? "settings-role-item settings-role-item--active" : "settings-role-item"
                    }
                    onClick={() => setSelectedKey(list.key)}
                  >
                    {list.displayName}
                  </button>
                </li>
              ))}
            </ul>
          </div>

          <div className="settings-roles-detail">
            {selectedList ? (
              <ValueListDetail
                listKey={selectedList.key}
                displayName={selectedList.displayName}
                canCreate={canCreate}
                canEdit={canEdit}
              />
            ) : (
              <p>Keine Liste ausgewählt.</p>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

function ValueListDetail({ listKey, displayName, canCreate, canEdit }) {
  const [items, setItems] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  const [newValue, setNewValue] = useState("");
  const [isCreating, setIsCreating] = useState(false);
  const [createError, setCreateError] = useState(null);

  const [usagesByItemId, setUsagesByItemId] = useState({});
  const [blockedDeleteId, setBlockedDeleteId] = useState(null);
  const [blockedUsages, setBlockedUsages] = useState([]);

  const isOrderStatus = listKey === ORDER_STATUS_KEY;
  const isCrmStatus = listKey === CRM_STATUS_KEY;
  const isQualification = listKey === QUALIFICATION_KEY;
  const columnCount = 5 + (isOrderStatus ? 2 : 0) + (isCrmStatus ? 1 : 0);

  const loadItems = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    setBlockedDeleteId(null);
    const result = await window.omsorg.valueLists.listItems(listKey);
    if (result.ok) {
      setItems(result.data ?? []);
    } else {
      setError("Werte konnten nicht geladen werden.");
    }
    setIsLoading(false);
  }, [listKey]);

  useEffect(() => {
    loadItems();
    setUsagesByItemId({});
  }, [loadItems]);

  async function handleCreate(event) {
    event.preventDefault();
    if (!newValue.trim()) {
      setCreateError("Wert ist erforderlich.");
      return;
    }

    setIsCreating(true);
    setCreateError(null);
    const result = await window.omsorg.valueLists.createItem(listKey, {
      value: newValue.trim(),
      sortOrder: items.length,
      isDefault: false,
      isInitial: false,
      isTerminal: false,
      triggersFollowUp: false,
    });
    setIsCreating(false);

    if (!result.ok) {
      setCreateError(result.status === 400 ? "Ungültiger Wert." : "Wert konnte nicht angelegt werden.");
      return;
    }

    setNewValue("");
    invalidateValueListCache(listKey);
    await loadItems();
  }

  async function handleSetDefault(item) {
    if (!canEdit) return;
    await window.omsorg.valueLists.updateItem(listKey, item.id, {
      value: item.value,
      sortOrder: item.sortOrder,
      isDefault: true,
      isInitial: item.isInitial,
      isTerminal: item.isTerminal,
      triggersFollowUp: item.triggersFollowUp,
    });
    invalidateValueListCache(listKey);
    await loadItems();
  }

  async function handleToggleFlag(item, flag) {
    if (!canEdit) return;
    await window.omsorg.valueLists.updateItem(listKey, item.id, {
      value: item.value,
      sortOrder: item.sortOrder,
      isDefault: item.isDefault,
      isInitial: flag === "isInitial" ? !item.isInitial : item.isInitial,
      isTerminal: flag === "isTerminal" ? !item.isTerminal : item.isTerminal,
      triggersFollowUp: flag === "triggersFollowUp" ? !item.triggersFollowUp : item.triggersFollowUp,
    });
    invalidateValueListCache(listKey);
    await loadItems();
  }

  async function handleMove(item, direction) {
    if (!canEdit) return;

    const sorted = [...items].sort((a, b) => a.sortOrder - b.sortOrder);
    const index = sorted.findIndex((i) => i.id === item.id);
    const swapIndex = index + direction;
    if (swapIndex < 0 || swapIndex >= sorted.length) return;

    const other = sorted[swapIndex];

    await Promise.all([
      window.omsorg.valueLists.updateItem(listKey, item.id, {
        value: item.value,
        sortOrder: other.sortOrder,
        isDefault: item.isDefault,
        isInitial: item.isInitial,
        isTerminal: item.isTerminal,
        triggersFollowUp: item.triggersFollowUp,
      }),
      window.omsorg.valueLists.updateItem(listKey, other.id, {
        value: other.value,
        sortOrder: item.sortOrder,
        isDefault: other.isDefault,
        isInitial: other.isInitial,
        isTerminal: other.isTerminal,
        triggersFollowUp: other.triggersFollowUp,
      }),
    ]);

    invalidateValueListCache(listKey);
    await loadItems();
  }

  async function handleShowUsages(item) {
    if (usagesByItemId[item.id]) {
      setUsagesByItemId((prev) => {
        const next = { ...prev };
        delete next[item.id];
        return next;
      });
      return;
    }

    const result = await window.omsorg.valueLists.getUsages(listKey, item.id);
    setUsagesByItemId((prev) => ({ ...prev, [item.id]: result.ok ? result.data ?? [] : [] }));
  }

  async function handleDelete(item) {
    if (!canEdit) return;
    setBlockedDeleteId(null);

    const result = await window.omsorg.valueLists.deleteItem(listKey, item.id);
    if (result.ok) {
      invalidateValueListCache(listKey);
      await loadItems();
      return;
    }

    if (result.status === 409) {
      setBlockedDeleteId(item.id);
      setBlockedUsages(result.data ?? []);
      return;
    }

    setError("Wert konnte nicht gelöscht werden.");
  }

  if (isLoading) {
    return <p>Lädt...</p>;
  }

  return (
    <div className="settings-permission-matrix">
      <h3>{displayName}</h3>
      {error && <p className="login-error">{error}</p>}

      {isQualification && (
        <p className="debug-sessions-meta">
          Reihenfolge = Rangfolge des Qualifikationsniveaus: oben das niedrigste Niveau, unten das höchste.
        </p>
      )}

      <div className="settings-permission-matrix-scroll">
        <table>
          <thead>
            <tr>
              <th>Rang</th>
              <th>Reihenfolge</th>
              <th>Wert</th>
              <th>Standard</th>
              {isOrderStatus && <th>Start</th>}
              {isOrderStatus && <th>Ende</th>}
              {isCrmStatus && <th>Löst Wiedervorlage aus</th>}
              <th></th>
            </tr>
          </thead>
          <tbody>
            {items.map((item, index) => (
              <Fragment key={item.id}>
                <tr key={item.id}>
                  <td>{index + 1}</td>
                  <td>
                    <div className="settings-sort-order-controls">
                      <OmsorgButton
                        icon={ArrowUp}
                        variant="secondary"
                        type="button"
                        disabled={!canEdit || index === 0}
                        onClick={() => handleMove(item, -1)}
                      />
                      <OmsorgButton
                        icon={ArrowDown}
                        variant="secondary"
                        type="button"
                        disabled={!canEdit || index === items.length - 1}
                        onClick={() => handleMove(item, 1)}
                      />
                    </div>
                  </td>
                  <td>{item.value}</td>
                  <td>
                    <input
                      type="radio"
                      name={`${listKey}-default`}
                      checked={item.isDefault}
                      disabled={!canEdit}
                      onChange={() => handleSetDefault(item)}
                    />
                  </td>
                  {isOrderStatus && (
                    <td>
                      <input
                        type="checkbox"
                        checked={item.isInitial}
                        disabled={!canEdit}
                        onChange={() => handleToggleFlag(item, "isInitial")}
                      />
                    </td>
                  )}
                  {isOrderStatus && (
                    <td>
                      <input
                        type="checkbox"
                        checked={item.isTerminal}
                        disabled={!canEdit}
                        onChange={() => handleToggleFlag(item, "isTerminal")}
                      />
                    </td>
                  )}
                  {isCrmStatus && (
                    <td>
                      <input
                        type="checkbox"
                        checked={item.triggersFollowUp}
                        disabled={!canEdit}
                        onChange={() => handleToggleFlag(item, "triggersFollowUp")}
                      />
                    </td>
                  )}
                  <td>
                    <OmsorgButton
                      icon={Info}
                      variant="secondary"
                      type="button"
                      onClick={() => handleShowUsages(item)}
                    >
                      Verwendung
                    </OmsorgButton>
                    {canEdit && (
                      <OmsorgButton
                        icon={Trash2}
                        variant="secondary"
                        type="button"
                        onClick={() => handleDelete(item)}
                      >
                        Löschen
                      </OmsorgButton>
                    )}
                  </td>
                </tr>
                {usagesByItemId[item.id] && (
                  <tr key={`${item.id}-usages`}>
                    <td colSpan={columnCount}>
                      {usagesByItemId[item.id].length === 0 ? (
                        <span className="debug-sessions-meta">Wird nirgends verwendet.</span>
                      ) : (
                        <span className="debug-sessions-meta">
                          Wird verwendet bei: {usagesByItemId[item.id].map((u) => u.displayLabel).join(", ")}
                        </span>
                      )}
                    </td>
                  </tr>
                )}
                {blockedDeleteId === item.id && (
                  <tr key={`${item.id}-blocked`}>
                    <td colSpan={columnCount}>
                      <p className="login-error">
                        Löschen nicht möglich - wird noch verwendet bei: {blockedUsages.map((u) => u.displayLabel).join(", ")}.
                        Bitte dort zuerst entfernen/ändern.
                      </p>
                    </td>
                  </tr>
                )}
              </Fragment>
            ))}
          </tbody>
        </table>
      </div>

      {canCreate && (
        <form onSubmit={handleCreate} className="settings-new-role-form">
          <input
            type="text"
            placeholder="Neuer Wert"
            value={newValue}
            onChange={(event) => setNewValue(event.target.value)}
          />
          <OmsorgButton icon={Plus} type="submit" variant="secondary" disabled={isCreating}>
            Anlegen
          </OmsorgButton>
        </form>
      )}
      {createError && <p className="login-error">{createError}</p>}

      {(isOrderStatus || isCrmStatus) && (
        <OrderStatusTransitions items={items} canEdit={canEdit} listKey={listKey} />
      )}
    </div>
  );
}

function OrderStatusTransitions({ items, canEdit, listKey }) {
  const [transitions, setTransitions] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [savedMessage, setSavedMessage] = useState(null);

  const loadTransitions = useCallback(async () => {
    setIsLoading(true);
    const result = await window.omsorg.valueLists.listTransitions(listKey);
    setTransitions(result.ok ? result.data ?? [] : []);
    setIsLoading(false);
  }, [listKey]);

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

  function isAllowed(fromId, toId) {
    return transitions.some((t) => t.fromItemId === fromId && t.toItemId === toId);
  }

  function toggle(fromId, toId) {
    if (!canEdit) return;
    setSavedMessage(null);
    setTransitions((prev) => {
      if (prev.some((t) => t.fromItemId === fromId && t.toItemId === toId)) {
        return prev.filter((t) => !(t.fromItemId === fromId && t.toItemId === toId));
      }
      return [...prev, { fromItemId: fromId, toItemId: toId }];
    });
  }

  async function handleSave() {
    setIsSaving(true);
    setSavedMessage(null);
    const result = await window.omsorg.valueLists.replaceTransitions(listKey, transitions);
    setIsSaving(false);
    setSavedMessage(result.ok ? "Gespeichert." : "Speichern fehlgeschlagen.");
  }

  if (isLoading) {
    return <p>Lädt Übergänge...</p>;
  }

  return (
    <div className="settings-permission-matrix" style={{ marginTop: "2rem" }}>
      <h3>Erlaubte Übergänge</h3>
      <div className="settings-permission-matrix-scroll">
        <table>
          <thead>
            <tr>
              <th>Von \ Nach</th>
              {items.map((to) => (
                <th key={to.id}>{to.value}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {items.map((from) => (
              <tr key={from.id}>
                <td>{from.value}</td>
                {items.map((to) => (
                  <td key={to.id}>
                    {from.id !== to.id && (
                      <input
                        type="checkbox"
                        checked={isAllowed(from.id, to.id)}
                        disabled={!canEdit}
                        onChange={() => toggle(from.id, to.id)}
                      />
                    )}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {canEdit && (
        <div className="settings-permission-matrix-actions">
          <OmsorgButton icon={Save} onClick={handleSave} disabled={isSaving}>
            {isSaving ? "Speichert..." : "Speichern"}
          </OmsorgButton>
          {savedMessage && <span className="debug-sessions-meta">{savedMessage}</span>}
        </div>
      )}
    </div>
  );
}
