// filepath: frontend/src/pages/TripChecklist.tsx
import React, { useState, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
import { getTripItems, toggleTripItem, updateTrip, getTags } from "../api";
import TagAutocompleteInput from "../components/TagAutocompleteInput";
import { getTagColor } from "../utils/tagColors";

export default function TripChecklist({ trips }: { trips: any[] }) {
  const { id } = useParams();
  const [items, setItems] = useState<any[]>([]);
  const [allTags, setAllTags] = useState<any[]>([]);
  const [tagInput, setTagInput] = useState("");
  const [hoveredTag, setHoveredTag] = useState<string | null>(null);
  const [addingTag, setAddingTag] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (id) {
      getTripItems(id).then(setItems);
      getTags().then(setAllTags);
    }
  }, [id]);

  const trip = trips.find((t) => t.id === id);
  const [selectedTags, setSelectedTags] = useState<any[]>([]);
  const [markedTags, setMarkedTags] = useState<any[]>([]);

  useEffect(() => {
    if (trip) {
      setSelectedTags(trip.selected_tags);
      setMarkedTags(trip.marked_tags);
    }
  }, [trip]);

  async function handleToggleMark(tagId: string) {
    const isMarked = markedTags.some((t) => t.id === tagId);
    const newMarked = isMarked
      ? markedTags.filter((t) => t.id !== tagId)
      : [...markedTags, selectedTags.find((t) => t.id === tagId)];
    await updateTrip(trip.id, {
      name: trip.name,
      start_date: trip.start_date,
      end_date: trip.end_date,
      selected_tag_ids: selectedTags.map((t) => t.id),
      marked_tag_ids: newMarked.map((t) => t.id),
    });
    setMarkedTags(newMarked);
    // Items neu laden
    if (id) {
      const updated = await getTripItems(id);
      setItems(updated);
    }
  }

  async function handleRemoveTag(tagId: string) {
    const newSelected = selectedTags.filter((t) => t.id !== tagId);
    const newMarked = markedTags.filter((t) => t.id !== tagId);
    await updateTrip(trip.id, {
      name: trip.name,
      start_date: trip.start_date,
      end_date: trip.end_date,
      selected_tag_ids: newSelected.map((t) => t.id),
      marked_tag_ids: newMarked.map((t) => t.id),
    });
    setSelectedTags(newSelected);
    setMarkedTags(newMarked);
    // Items neu laden
    if (id) {
      const updated = await getTripItems(id);
      setItems(updated);
    }
  }

  async function handleAddTag(tagId: string) {
    if (selectedTags.some((t) => t.id === tagId)) return;
    const tagObj = allTags.find((t) => t.id === tagId);
    const newSelected = [...selectedTags, tagObj];
    await updateTrip(trip.id, {
      name: trip.name,
      start_date: trip.start_date,
      end_date: trip.end_date,
      selected_tag_ids: newSelected.map((t) => t.id),
      marked_tag_ids: markedTags.map((t) => t.id),
    });
    setSelectedTags(newSelected);
    setTagInput("");
    // Items neu laden
    if (id) {
      const updated = await getTripItems(id);
      setItems(updated);
    }
  }

  if (!trip) return <div>Trip not found</div>;

  // 1. Items ohne Tag
  const itemsWithoutTag = items.filter((item) => !item.tag);

  // 2. Items mit Tag, gruppiert nach tag.id
  const itemsByTag: Record<string, { tag: any; items: any[] }> = {};
  items
    .filter((item) => item.tag)
    .forEach((item) => {
      const tagId = item.tag.id;
      if (!itemsByTag[tagId]) {
        itemsByTag[tagId] = { tag: item.tag, items: [] };
      }
      itemsByTag[tagId].items.push(item);
    });

  // Nur markierte Tag-Gruppen
  const markedTagIds = new Set(markedTags.map((t: any) => t.id));
  const markedTagGroups = Object.values(itemsByTag)
    .filter((g) => markedTagIds.has(g.tag.id))
    .sort((a, b) => a.tag.name.localeCompare(b.tag.name));

  // Hilfsfunktion für Kategorie-Gruppierung
  function renderItemsWithCategories(items: any[]) {
    const slashCategoryMap: Record<string, any[]> = {};
    const normalItems: any[] = [];
    items.forEach((item) => {
      const name = item.name_calculated || "";
      if (name.includes("/")) {
        const [cat, sub] = name.split("/", 2);
        if (!slashCategoryMap[cat]) slashCategoryMap[cat] = [];
        slashCategoryMap[cat].push({ ...item, _sub: sub });
      } else {
        normalItems.push(item);
      }
    });

    return (
      <>
        {/* Haupt-Items als Grid */}
        {normalItems.length > 0 && (
          <ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-4 mb-4">
            {normalItems.map((item) => (
              <li
                key={item.id}
                className={
                  "flex items-center gap-2 cursor-pointer select-none px-2 py-1 rounded group " +
                  (item.checked ? "bg-green-100" : "hover:bg-gray-100")
                }
                onClick={async () => {
                  await toggleTripItem(item.id);
                  const updated = await getTripItems(id!);
                  setItems(updated);
                }}
              >
                <input
                  type="checkbox"
                  checked={item.checked}
                  readOnly
                  tabIndex={-1}
                  className="pointer-events-none"
                />
                <span
                  className={item.checked ? "line-through text-gray-400" : ""}
                  title={
                    item.item && item.item.tags && item.item.tags.length > 0
                      ? item.item.tags
                          .map(
                            (tag: any) =>
                              `#${tag.name}${tag.mandatory ? " *" : ""}`
                          )
                          .join(" ")
                      : ""
                  }
                >
                  {item.name_calculated}
                </span>
                {/* Tags NICHT mehr direkt anzeigen */}
              </li>
            ))}
          </ul>
        )}
        {/* Slash-Kategorien wie gehabt */}
        {Object.entries(slashCategoryMap).map(([cat, catItems]) => (
          <React.Fragment key={cat}>
            <li className="mt-2 mb-1 flex items-center gap-2">
              <h3 className="text-base font-semibold text-gray-600 m-0">
                {cat.charAt(0).toUpperCase() + cat.slice(1)}
              </h3>
            </li>
            <ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-4">
              {catItems.map((item) => (
                <li
                  key={item.id}
                  className={
                    "flex items-center gap-2 cursor-pointer select-none px-2 py-1 rounded group " +
                    (item.checked ? "bg-green-100" : "hover:bg-gray-100")
                  }
                  onClick={async () => {
                    await toggleTripItem(item.id);
                    const updated = await getTripItems(id!);
                    setItems(updated);
                  }}
                >
                  <input
                    type="checkbox"
                    checked={item.checked}
                    readOnly
                    tabIndex={-1}
                    className="pointer-events-none"
                  />
                  <span
                    className={item.checked ? "line-through text-gray-400" : ""}
                    title={
                      item.item && item.item.tags && item.item.tags.length > 0
                        ? item.item.tags
                            .map(
                              (tag: any) =>
                                `#${tag.name}${tag.mandatory ? " *" : ""}`
                            )
                            .join(" ")
                        : ""
                    }
                  >
                    {item._sub}
                  </span>
                  {/* Tags NICHT mehr direkt anzeigen */}
                </li>
              ))}
            </ul>
          </React.Fragment>
        ))}
      </>
    );
  }

  function formatAsHeading(str: string) {
    if (!str) return "";
    // Replace hyphens with spaces and capitalize first letter
    const withSpaces = str.replace(/-/g, " ");
    return withSpaces.charAt(0).toUpperCase() + withSpaces.slice(1);
  }

  // Progress calculation
  const totalItems = items.length;
  const checkedItems = items.filter((item) => item.checked).length;
  const progress = totalItems > 0 ? Math.round((checkedItems / totalItems) * 100) : 0;

  // Progress gradient for header background (always full width)
  const progressGradient = `linear-gradient(140deg, #f59e42 0%, #facc15 50%, #22c55e 100%)`;

  return (
    <div className="py-4 max-w-5xl mx-auto">
      <div
        className="mb-6 px-4 py-3 rounded-xl shadow flex flex-wrap items-center gap-4 relative"
        style={{
          background: progressGradient,
          transition: "background 0.3s",
          overflow: "hidden",
        }}
      >
        {/* Overlay: shrinking box from the right */}
        <div
          style={{
            position: "absolute",
            top: 0,
            right: 0,
            bottom: 0,
            width: `${100 - progress}%`,
            background: "rgba(255, 255, 255, 0.85)",
            pointerEvents: "none",
            transition: "width 0.3s",
            zIndex: 1,
          }}
        />
        <div className="flex flex-col flex-1 min-w-[180px]" style={{ position: "relative", zIndex: 2 }}>
          <div className="flex items-end gap-2">
            <h2 className="text-xl text-gray-900 font-bold m-0">{trip.name}</h2>
            <span className="text-xs text-gray-500 px-2 py-0.5 rounded font-semibold">
              {trip.start_date} – {trip.end_date}
            </span>
          </div>
          <div className="flex flex-wrap gap-2 items-center mt-2">
            {selectedTags.length === 0 ? (
              <span className="text-gray-400 text-sm">keine</span>
            ) : (
              selectedTags.map((tag: any) => {
                const isMarked = markedTags.some((mt: any) => mt.id === tag.id);
                const color = getTagColor(tag.id);
                return (
                  <span
                    key={tag.id}
                    className={
                      `relative px-2 py-0.5 rounded mr-1 text-xs shadow shadow-md cursor-pointer transition font-medium ${color.bg} ` +
                      (isMarked ? "ring-2 ring-yellow-400" : "")
                    }
                    onClick={() => handleToggleMark(tag.id)}
                    onMouseEnter={() => setHoveredTag(tag.id)}
                    onMouseLeave={() => setHoveredTag(null)}
                  >
                    #{tag.name}
                    {tag.mandatory && <span className="text-red-500 font-bold ml-0.5">!</span>}
                    {hoveredTag === tag.id && (
                      <button
                        className="absolute -top-2 -right-2 text-xs text-red-500 bg-white rounded-full px-1 shadow"
                        onClick={e => {
                          e.stopPropagation();
                          handleRemoveTag(tag.id);
                        }}
                      >
                        ×
                      </button>
                    )}
                  </span>
                );
              })
            )}
            {/* "+Tag" link and dropdown */}
            {!addingTag ? (
              <button
                className="text-blue-500 underline text-xs ml-2"
                onClick={() => {
                  setAddingTag(true);
                  setTimeout(() => {
                    inputRef.current?.focus();
                  }, 0);
                }}
                type="button"
              >
                + Tag
              </button>
            ) : (
              <TagAutocompleteInput
                ref={inputRef}
                allTags={allTags}
                selectedTags={selectedTags}
                onAddTag={(tagId, viaTab) => {
                  handleAddTag(tagId);
                  if (viaTab) {
                    setTimeout(() => {
                      setAddingTag(true);
                      inputRef.current?.focus();
                    }, 0);
                  } else {
                    setAddingTag(false);
                  }
                }}
                onEscape={() => setAddingTag(false)}
                placeholder="Tag suchen..."
              />
            )}
          </div>
        </div>
        {/* Fortschritt kompakt rechts */}
        <div className="flex flex-col items-end min-w-[120px]" style={{ position: "relative", zIndex: 2 }}>
          <span className="font-semibold text-gray-700 text-sm">Fortschritt</span>
          <span className="text-xs text-gray-500">{checkedItems} / {totalItems}</span>
          <span className="text-xs text-gray-500">{progress}%</span>
        </div>
      </div>
      {/* ...restliche Seite... */}
      <ul
        className="grid grid-cols-1 gap-x-8 gap-y-2"
      >
        {/* 1. Ohne Tag */}
        {renderItemsWithCategories(itemsWithoutTag)}

        {/* 2. Markierte Tag-Gruppen */}
        {markedTagGroups.map(({ tag, items }) => (
          <li
            key={tag.id}
            className="mt-6 mb-6 p-4 rounded-lg border-2 border-yellow-200 bg-yellow-50 shadow-sm"
            style={{ listStyle: "none" }}
          >
            <div className="mb-2 flex items-center gap-2">
              <h2 className="text-lg font-bold text-yellow-700 m-0">
                {formatAsHeading(tag.name)}
              </h2>
            </div>
            <ul>
              {renderItemsWithCategories(items)}
            </ul>
          </li>
        ))}
      </ul>
    </div>
  );
}