import { useState } from 'react';
import type { ProcessNode } from '../../types/process';
import SubprocessCard from './SubprocessCard';
import './ProcessGroupList.css';

interface GroupCoords {
  lat?: string | number | null;
  lon?: string | number | null;
  hours?: string;
  box_scale?: string | number;
}

interface Props {
  processes: ProcessNode[];
  groups: number[][];
  groupNames: string[];
  groupCoordinates: Record<string, GroupCoords>;
  onProcessesChange: (p: ProcessNode[]) => void;
  onGroupsChange: (g: number[][]) => void;
  onGroupNamesChange: (n: string[]) => void;
  onGroupCoordinatesChange: (c: Record<string, GroupCoords>) => void;
  onPlaceRequest: (target: string) => void;
  placementTarget: string | null;
  subprocessMapExpanded: Record<number, boolean>;
  onSubprocessMapToggle: (gIdx: number) => void;

  expandedGroups?: Set<number>;
  onExpandedGroupsChange?: (set: Set<number>) => void;
}

export default function ProcessGroupList({
  processes,
  groups,
  groupNames,
  groupCoordinates,
  onProcessesChange,
  onGroupsChange,
  onGroupNamesChange,
  onGroupCoordinatesChange,
  onPlaceRequest,
  placementTarget,
  subprocessMapExpanded,
  onSubprocessMapToggle,

  expandedGroups = new Set(),
  onExpandedGroupsChange,
}: Props) {
  const [infoExpanded, setInfoExpanded] = useState<Set<number>>(new Set());
  const [confirmDelete, setConfirmDelete] = useState<number | null>(null);

  const toggleGroup = (idx: number) => {
    // If we're clicking an already expanded group, collapse it
    if (expandedGroups.has(idx)) {
      if (subprocessMapExpanded[idx]) {
        onSubprocessMapToggle(idx);
      }
      onExpandedGroupsChange?.(new Set()); // Collapse all
    } else {
      // Otherwise, ONLY expand the new one
      onExpandedGroupsChange?.(new Set([idx]));
    }
  };

  const toggleInfo = (idx: number) => {
    setInfoExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(idx)) next.delete(idx);
      else next.add(idx);
      return next;
    });
  };

  const updateGroupName = (gIdx: number, name: string) => {
    const names = [...groupNames];
    names[gIdx] = name;
    onGroupNamesChange(names);
  };

  const updateGroupCoord = (
    gIdx: number,
    field: string,
    value: string | number
  ) => {
    const coords = { ...groupCoordinates };
    coords[gIdx] = { ...(coords[gIdx] || {}), [field]: value };
    onGroupCoordinatesChange(coords);
  };

  const deleteGroup = (gIdx: number) => {
    const newGroups = groups.filter((_, i) => i !== gIdx);
    const newNames = groupNames.filter((_, i) => i !== gIdx);
    const newCoords = { ...groupCoordinates };
    delete newCoords[gIdx];
    // Re-index coordinates
    const reindexed: Record<string, GroupCoords> = {};
    Object.keys(newCoords).forEach((k) => {
      const oldIdx = parseInt(k);
      const newIdx = oldIdx > gIdx ? oldIdx - 1 : oldIdx;
      reindexed[newIdx] = newCoords[oldIdx];
    });
    onGroupsChange(newGroups);
    onGroupNamesChange(newNames);
    onGroupCoordinatesChange(reindexed);
    setConfirmDelete(null);
  };

  const addSubprocess = (gIdx: number) => {
    const newProcesses = [...processes];
    const newSub: ProcessNode = {
      name: `Subprocess ${newProcesses.length + 1}`,
      lat: '',
      lon: '',
      box_scale: 1.0,
      next: '',
      hours: '',
      extra_info: { notes: '' },
      streams: [],
      children: [],
    };
    const newIdx = newProcesses.length;
    newProcesses.push(newSub);

    const newGroups = [...groups];
    newGroups[gIdx] = [...newGroups[gIdx], newIdx];

    onProcessesChange(newProcesses);
    onGroupsChange(newGroups);
  };

  const updateSubprocess = (subIdx: number, updated: ProcessNode) => {
    const newProcesses = [...processes];
    newProcesses[subIdx] = updated;
    onProcessesChange(newProcesses);
  };

  const deleteSubprocess = (gIdx: number, subIdx: number) => {
    const newGroups = [...groups];
    newGroups[gIdx] = newGroups[gIdx].filter((i) => i !== subIdx);
    // Don't remove from processes array to avoid re-indexing issues
    // Just remove from group
    if (newGroups[gIdx].length === 0) {
      // Remove empty group
      deleteGroup(gIdx);
    } else {
      onGroupsChange(newGroups);
    }
  };

  return (
    <div className="pgl">
      {groups.map((subIdxs, gIdx) => {
        const expanded = expandedGroups.has(gIdx);
        const showInfo = infoExpanded.has(gIdx);
        const gCoords = groupCoordinates[gIdx] || {};
        const isPlacing = placementTarget === `group_${gIdx}`;

        return (
          <div key={gIdx} className="pgl-group card" id={`group-list-item-${gIdx}`}>
            {/* Group header */}
            <div className="pgl-group-header">
              <button
                className="pgl-toggle"
                onClick={() => toggleGroup(gIdx)}
                title={expanded ? 'Collapse' : 'Expand'}
              >
                <span
                  className={`collapsible-arrow ${expanded ? 'open' : ''}`}
                >
                  ▶
                </span>
              </button>

              <input
                type="text"
                className="pgl-name-input"
                value={groupNames[gIdx] || ''}
                onChange={(e) => updateGroupName(gIdx, e.target.value)}
              />

              <div className="pgl-scale">
                <input
                  type="range"
                  min={0.5}
                  max={3}
                  step={0.1}
                  value={gCoords.box_scale ?? 1.5}
                  onChange={(e) =>
                    updateGroupCoord(gIdx, 'box_scale', parseFloat(e.target.value))
                  }
                  title={`Box size: ${gCoords.box_scale ?? 1.5}`}
                />
              </div>

              <button
                className={`btn btn-sm ${isPlacing ? 'btn-primary' : ''}`}
                onClick={() =>
                  onPlaceRequest(isPlacing ? '' : `group_${gIdx}`)
                }
              >
                {isPlacing ? 'Done' : 'Place'}
              </button>

              <span className="pgl-badge">{subIdxs.length} sub</span>

              {confirmDelete === gIdx ? (
                <span className="pgl-confirm">
                  <button
                    className="btn btn-sm btn-danger"
                    onClick={() => deleteGroup(gIdx)}
                  >
                    ✅
                  </button>
                  <button
                    className="btn btn-sm"
                    onClick={() => setConfirmDelete(null)}
                  >
                    ❌
                  </button>
                </span>
              ) : (
                <button
                  className="btn btn-sm"
                  onClick={() => setConfirmDelete(gIdx)}
                  title="Delete group"
                >
                  ✕
                </button>
              )}
            </div>

            {/* Expanded content */}
            {expanded && (
              <div className="pgl-group-body">
                {/* Info section */}
                <div className="pgl-section">
                  <div
                    className="pgl-section-header"
                    onClick={() => toggleInfo(gIdx)}
                  >
                    <span
                      className={`collapsible-arrow ${showInfo ? 'open' : ''}`}
                    >
                      ▶
                    </span>
                    <span>Information</span>
                  </div>
                  {showInfo && (
                    <div className="pgl-info-grid">
                      <div>
                        <label>Latitude</label>
                        <input
                          type="text"
                          value={gCoords.lat || ''}
                          onChange={(e) =>
                            updateGroupCoord(gIdx, 'lat', e.target.value)
                          }
                        />
                      </div>
                      <div>
                        <label>Longitude</label>
                        <input
                          type="text"
                          value={gCoords.lon || ''}
                          onChange={(e) =>
                            updateGroupCoord(gIdx, 'lon', e.target.value)
                          }
                        />
                      </div>
                      <div>
                        <label>Hours</label>
                        <input
                          type="text"
                          value={gCoords.hours || ''}
                          onChange={(e) =>
                            updateGroupCoord(gIdx, 'hours', e.target.value)
                          }
                        />
                      </div>
                    </div>
                  )}
                </div>

                {/* Subprocesses */}
                <div className="pgl-section">
                  <div className="pgl-section-header flex justify-between items-center">
                    <span>
                      Subprocesses ({subIdxs.length})
                    </span>
                    <div className="flex gap-xs">
                      <button
                        className="btn btn-sm"
                        onClick={() => onSubprocessMapToggle(gIdx)}
                      >
                        {subprocessMapExpanded[gIdx]
                          ? '🔽 Hide Map'
                          : '🗺️ Show on Map'}
                      </button>
                      <button
                        className="btn btn-sm btn-primary"
                        onClick={() => addSubprocess(gIdx)}
                      >
                        ➕ Add
                      </button>
                    </div>
                  </div>

                  {subIdxs.map((si) => {
                    const sub = processes[si];
                    if (!sub) return null;
                    return (
                      <SubprocessCard
                        key={si}
                        id={`sub-card-${si}`}
                        subprocess={sub}
                        subIdx={si}
                        groupIdx={gIdx}
                        allProcessNames={subIdxs.map((idx) => processes[idx]?.name).filter(Boolean)}
                        onUpdate={(updated) => updateSubprocess(si, updated)}
                        onDelete={() => deleteSubprocess(gIdx, si)}
                        onPlaceRequest={onPlaceRequest}
                        placementTarget={placementTarget}
                      />
                    );
                  })}
                </div>
              </div>
            )}
          </div>
        );
      })}

      {groups.length === 0 && (
        <div className="pgl-empty">
          <p>No processes yet. Click <strong>Add Process</strong> to begin.</p>
        </div>
      )}
    </div>
  );
}
