// Rôle : fournit l'outil checklist avec quantités, catégories et imports texte.
import { useCallback, useState } from "react";
import { Icon } from "../../../components/Icon.jsx";
import { TextImportModal } from "./TextImportModal.jsx";
import { parseColonImportLines } from "./textImport.js";

export function ChecklistModule({ toolboxId, moduleId, context, editing }) {
  const data = context.normalizeChecklistData(context.getModuleData(toolboxId, moduleId, { items: [] }));
  const textContent = context.moduleText?.checklist || {};
  const [label, setLabel] = useState("");
  const [sectionTitle, setSectionTitle] = useState("");
  const [qty, setQty] = useState(1);
  const [textImport, setTextImport] = useState("");
  const [importOpen, setImportOpen] = useState(false);
  const closeImportModal = useCallback(() => setImportOpen(false), []);
  const namedSections = data.sections.filter((section) => section.title);
  const completedSectionsMode = data.hideCompletedSectionsFully ? "hidden" : data.hideCompletedSections ? "reduced" : "visible";

  function save(sections, settings = {}) {
    context.setModuleData(toolboxId, moduleId, { ...data, ...settings, sections });
  }

  function appendItems(sections, title, items) {
    const cleanTitle = title.trim();
    const existingIndex = sections.findIndex((section) => section.title.toLowerCase() === cleanTitle.toLowerCase());
    if (existingIndex >= 0) {
      return sections.map((section, index) => index === existingIndex ? { ...section, items: [...section.items, ...items] } : section);
    }
    return [...sections, { id: context.uid("section"), title: cleanTitle, items }];
  }

  function addItem(event) {
    event.preventDefault();
    const cleanLabel = label.trim();
    if (!cleanLabel) return;
    const nextItem = { id: context.uid("item"), label: cleanLabel, qtyTarget: Math.max(1, Number(qty) || 1), qtyCurrent: 0 };
    save(appendItems(data.sections, sectionTitle, [nextItem]));
    setLabel("");
    setQty(1);
  }

  function importItems(event) {
    event.preventDefault();
    const importedSections = parseChecklistImport(textImport, context);
    if (!importedSections.length) return;
    const nextSections = importedSections.reduce((sections, section) => appendItems(sections, section.title, section.items), data.sections);
    save(nextSections);
    setTextImport("");
    setImportOpen(false);
    context.notify?.("Import checklist terminé.");
  }

  function setCompletedSectionsMode(mode) {
    save(data.sections.map((section) => ({ ...section, hideWhenComplete: undefined })), {
      hideCompletedSections: mode === "reduced",
      hideCompletedSectionsFully: mode === "hidden"
    });
  }

  return (
    <>
      {editing && (
        <div className="module-add-panel">
          <form className="inline-form checklist-add-form" onSubmit={addItem}>
            <input name="section" placeholder={textContent.sectionPlaceholder || "Catégorie"} value={sectionTitle} onChange={(event) => setSectionTitle(event.target.value)} />
            <input name="label" placeholder={textContent.itemPlaceholder || "Nouvel item"} value={label} onChange={(event) => setLabel(event.target.value)} />
            <input className="checklist-qty-input" name="qty" type="number" min="1" value={qty} onChange={(event) => setQty(event.target.value)} aria-label={textContent.quantityLabel || "Quantité cible"} />
            <button className="primary">{textContent.addButton || "Ajouter"}</button>
          </form>
          <div className="text-import-actions">
            <button type="button" onClick={() => setImportOpen(true)}>
              <Icon name="import" />
              <span>{textContent.importOpenButton || "Importer du texte"}</span>
            </button>
          </div>
        </div>
      )}
      {importOpen && (
        <TextImportModal
          title={textContent.importModalTitle || "Importer une checklist"}
          value={textImport}
          onChange={setTextImport}
          placeholder={textContent.importPlaceholder || "Importer plusieurs items...\nPotion:10\nMéga potion:5"}
          submitLabel={textContent.importButton || "Importer le texte"}
          onSubmit={importItems}
          onClose={closeImportModal}
        />
      )}
      {namedSections.length > 0 && (
        <div className="checklist-toolbar" role="radiogroup" aria-label={textContent.completedSectionsModeTitle || "Affichage des catégories terminées"}>
          {[
            { mode: "visible", label: textContent.completedSectionsVisibleLabel || "Visible", icon: "eye-open" },
            { mode: "reduced", label: textContent.completedSectionsReducedLabel || "Réduit", icon: "hide" },
            { mode: "hidden", label: textContent.completedSectionsHiddenLabel || "Caché", icon: "eye-closed" }
          ].map((option) => (
            <button
              className={`checklist-complete-mode-button ${completedSectionsMode === option.mode ? "active" : ""}`}
              type="button"
              role="radio"
              aria-checked={completedSectionsMode === option.mode}
              aria-label={option.label}
              key={option.mode}
              onClick={() => setCompletedSectionsMode(option.mode)}
              title={option.label}
            >
              <Icon name={option.icon} />
            </button>
          ))}
        </div>
      )}
      <ul className="checklist">
        {data.sections.map((section) => (
          <ChecklistSection key={section.id} section={section} sections={data.sections} data={data} context={context} save={save} />
        ))}
      </ul>
    </>
  );
}

function parseChecklistImport(text, context) {
  const sections = [];
  let currentSection = { id: context.uid("section"), title: "", items: [] };

  String(text || "").split(/\r?\n/).forEach((line) => {
    const cleanLine = line.trim();
    if (!cleanLine) return;
    if (cleanLine.startsWith("#")) {
      if (currentSection.items.length || currentSection.title) sections.push(currentSection);
      currentSection = { id: context.uid("section"), title: cleanLine.replace(/^#+/, "").trim(), items: [] };
      return;
    }
    parseColonImportLines(cleanLine).forEach((entry) => {
      currentSection.items.push({
        id: context.uid("item"),
        label: entry.label,
        qtyTarget: Math.max(1, Number.parseInt(entry.value, 10) || 1),
        qtyCurrent: 0
      });
    });
  });

  if (currentSection.items.length || currentSection.title) sections.push(currentSection);
  return sections.filter((section) => section.items.length);
}

function isSectionComplete(section, context) {
  return section.items.length > 0 && section.items.every((item) => context.clampQty(item.qtyCurrent, item.qtyTarget) >= item.qtyTarget);
}

function getSectionHideWhenComplete(section, globalHide) {
  return typeof section.hideWhenComplete === "boolean" ? section.hideWhenComplete : globalHide;
}

function CategoryTitle({ title }) {
  return String(title || "").split(/([♂♀])/g).map((part, index) => (
    part === "♂" || part === "♀"
      ? <span className="checklist-gender-symbol" key={index}>{part}</span>
      : part
  ));
}

function ChecklistSection({ section, context, sections, data, save }) {
  const showTitle = Boolean(section.title);
  const sectionComplete = showTitle && isSectionComplete(section, context);
  const hideWhenComplete = getSectionHideWhenComplete(section, data.hideCompletedSections);
  const isAutoCollapsed = sectionComplete && hideWhenComplete;
  const isCollapsed = Boolean(section.collapsed) || isAutoCollapsed;

  if (sectionComplete && data.hideCompletedSectionsFully) return null;

  function saveItems(items) {
    save(sections.map((entry) => entry.id === section.id ? { ...entry, items } : entry).filter((entry) => entry.items.length || entry.title));
  }

  function toggleSectionCollapsed() {
    const nextCollapsed = !isCollapsed;
    const nextSections = sections.map((entry) => {
      if (entry.id === section.id) {
        const nextSection = { ...entry };
        if (nextCollapsed) {
          if (sectionComplete) {
            nextSection.hideWhenComplete = true;
            delete nextSection.collapsed;
          } else {
            nextSection.collapsed = true;
          }
        } else {
          delete nextSection.collapsed;
          if (sectionComplete) nextSection.hideWhenComplete = false;
        }
        return nextSection;
      }
      if (data.hideCompletedSections && !nextCollapsed && entry.title && isSectionComplete(entry, context)) return { ...entry, hideWhenComplete: true };
      return entry;
    });
    const nextCompletedSections = nextSections.filter((entry) => entry.title && isSectionComplete(entry, context));
    const allHidden = nextCompletedSections.length > 0 && nextCompletedSections.every((entry) => getSectionHideWhenComplete(entry, false));
    save(nextSections, { hideCompletedSections: allHidden });
  }

  return (
    <li className={`checklist-section ${showTitle ? "is-grouped" : ""} ${sectionComplete ? "is-complete" : ""} ${isCollapsed ? "is-collapsed" : ""}`}>
      {showTitle && (
        <div className="checklist-section-header">
          <h3><CategoryTitle title={section.title || "Sans catégorie"} /></h3>
          <div>
            <span>{section.items.filter((item) => context.clampQty(item.qtyCurrent, item.qtyTarget) >= item.qtyTarget).length} / {section.items.length}</span>
            <button
              className="checklist-section-collapse-button"
              type="button"
              onClick={toggleSectionCollapsed}
              aria-expanded={!isCollapsed}
              title={isCollapsed ? context.moduleText?.checklist?.showCompletedSectionTitle || "Afficher cette catégorie" : context.moduleText?.checklist?.hideCompletedSectionTitle || "Réduire cette catégorie"}
              aria-label={isCollapsed ? context.moduleText?.checklist?.showCompletedSectionTitle || "Afficher cette catégorie" : context.moduleText?.checklist?.hideCompletedSectionTitle || "Réduire cette catégorie"}
            >
              <Icon name={isCollapsed ? "chevron-down" : "chevron-up"} />
            </button>
          </div>
        </div>
      )}
      {!isCollapsed && (
        <ul className="checklist-section-items">
          {section.items.map((item) => (
            <ChecklistItem key={item.id} item={item} context={context} items={section.items} save={saveItems} />
          ))}
        </ul>
      )}
    </li>
  );
}

function ChecklistItem({ item, context, items, save }) {
  const done = context.clampQty(item.qtyCurrent, item.qtyTarget) >= item.qtyTarget;

  function updateItem(updater) {
    save(items.map((entry) => entry.id === item.id ? updater(entry) : entry));
  }

  return (
    <li className={`checklist-item ${done ? "is-complete" : ""}`}>
      <div className="checklist-item-main">
        {item.qtyTarget === 1 ? (
          <input
            type="checkbox"
            checked={done}
            onChange={(event) => updateItem((entry) => ({ ...entry, qtyTarget: 1, qtyCurrent: event.target.checked ? 1 : 0 }))}
            aria-label={`Terminer ${item.label}`}
          />
        ) : (
          <div className="checklist-qty-controls" aria-label={`Quantité ${item.label}`}>
            <button type="button" onClick={() => updateItem((entry) => ({ ...entry, qtyCurrent: context.clampQty(entry.qtyCurrent - 1, entry.qtyTarget) }))} aria-label={context.moduleText?.checklist?.decrementLabel || "Retirer une quantité"}>-</button>
            <label className="checklist-qty-current">
              <input
                type="number"
                max={item.qtyTarget}
                value={context.clampQty(item.qtyCurrent, item.qtyTarget)}
                style={{ "--qty-current-digits": String(context.clampQty(item.qtyCurrent, item.qtyTarget)).length }}
                onChange={(event) => updateItem((entry) => ({ ...entry, qtyCurrent: context.clampQty(event.target.value, entry.qtyTarget) }))}
                aria-label={`${context.moduleText?.checklist?.currentQuantityLabel || "Quantité actuelle"} ${item.label}`}
              />
              <span>/ {item.qtyTarget}</span>
            </label>
            <button type="button" onClick={() => updateItem((entry) => ({ ...entry, qtyCurrent: context.clampQty(entry.qtyCurrent + 1, entry.qtyTarget) }))} aria-label={context.moduleText?.checklist?.incrementLabel || "Ajouter une quantité"}>+</button>
          </div>
        )}
        <span>{item.label}</span>
      </div>
      <button className="checklist-delete-button danger" onClick={() => save(items.filter((entry) => entry.id !== item.id))} aria-label={`${context.moduleText?.checklist?.deleteTitle || "Supprimer"} ${item.label}`} title={context.moduleText?.checklist?.deleteTitle || "Supprimer"}>
        <Icon name="trash" />
      </button>
    </li>
  );
}
