import { useEffect, useMemo, useRef, useState } from 'react';
import { formatChangeType } from '../../data/historyUtils';
import { ModalPortal } from './ModalPortal';

const FILE_ICON = 'assets/file.svg';
const FOLDER_ICON = 'assets/folder.svg';

function todayStamp() {
  const d = new Date();
  const pad = (n) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

/**
 * The submit-a-changelist popup, shaped exactly like the revision-detail view:
 * same card, meta strip, file list, and pill actions — but the description is
 * editable, the file rows toggle inclusion, and the right button is the blue
 * "Submit Changes".
 *
 * `items`: [{ path, change, needsCheckout }] — the changelist under the scope
 * the user submitted from. `folders`: marked folder deletes in scope.
 */
export function SubmitModal({ items, folders, nextRevision, busy, onSubmit, onClose }) {
  // Rows are files plus folder-delete entries; everything starts included.
  const rows = useMemo(
    () => [
      ...folders.map((folder) => ({ key: `dir:${folder}`, path: folder, change: 'deleted', isFolder: true })),
      ...items.map((item) => ({ key: item.path, ...item })),
    ],
    [items, folders]
  );
  const [included, setIncluded] = useState(() => new Set(rows.map((row) => row.key)));
  const [description, setDescription] = useState('');
  const modalRef = useRef(null);

  useEffect(() => {
    modalRef.current?.focus();
  }, []);

  useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);

  const allSelected = included.size === rows.length;
  const toggleRow = (key) => {
    setIncluded((prev) => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
  };
  const toggleAll = () => {
    setIncluded(allSelected ? new Set() : new Set(rows.map((row) => row.key)));
  };

  const needsCheckout = rows.some(
    (row) => included.has(row.key) && row.change === 'edited' && row.needsCheckout
  );

  const handleSubmitClick = () => {
    if (included.size === 0 || busy) return;
    const chosenFiles = items.filter((item) => included.has(item.path));
    const chosenFolders = folders.filter((folder) => included.has(`dir:${folder}`));
    onSubmit(chosenFiles, chosenFolders, description.trim());
  };

  return (
    <ModalPortal>
      <div className="app-modal-overlay" onMouseDown={onClose}>
        <div
          ref={modalRef}
          className="app-modal app-modal--revision"
          role="dialog"
          aria-modal="true"
          aria-label="Submit a new revision"
          tabIndex={-1}
          onMouseDown={(e) => e.stopPropagation()}
        >
          <button type="button" className="app-modal-close" onClick={onClose} aria-label="Close">
            <img src="assets/close.svg" alt="" />
          </button>

          <div className="revision-modal-header">
            <div className="revision-modal-identity">
              <div className="revision-modal-name">Submit a new revision</div>
            </div>
          </div>

          <div className="revision-modal-meta">
            <div className="revision-modal-meta-item">
              <span className="revision-modal-meta-label">Revision</span>
              <span className="revision-modal-meta-value">{nextRevision}</span>
            </div>
            <div className="revision-modal-meta-item">
              <span className="revision-modal-meta-label">Date</span>
              <span className="revision-modal-meta-value">{todayStamp()}</span>
            </div>
            <div className="revision-modal-meta-item">
              <span className="revision-modal-meta-label">Files changed</span>
              <span className="revision-modal-meta-value">
                {included.size}/{rows.length}
              </span>
            </div>
          </div>

          <textarea
            className="revision-modal-description submit-description"
            placeholder="Enter a description of your changes"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            rows={3}
          />

          <div className="revision-modal-files">
            <ul className="revision-file-list">
              {rows.map((row, index) => {
                const selected = included.has(row.key);
                return (
                  <li key={row.key}>
                    <button
                      type="button"
                      className={`revision-file-row${index % 2 === 1 ? ' revision-file-row--alt' : ''}${selected ? ' revision-file-row--selected' : ' submit-file-row--excluded'}`}
                      onClick={() => toggleRow(row.key)}
                    >
                      <img src={row.isFolder ? FOLDER_ICON : FILE_ICON} alt="" className="revision-file-icon" />
                      <span className="revision-file-path">
                        {row.isFolder ? `${row.path}/` : row.path}
                      </span>
                      <span className="revision-file-type">({formatChangeType(row.change)})</span>
                    </button>
                  </li>
                );
              })}
            </ul>
          </div>

          <p className="submit-hint">
            Confirm you have selected all the files you want to change on the server.
          </p>
          {needsCheckout && (
            <p className="submit-hint submit-hint--warning">
              You have changed some files you haven't checked out. A checkout will be
              attempted to allow you to submit.
            </p>
          )}

          <div className="revision-modal-actions">
            <button type="button" className="revision-pill-btn" onClick={toggleAll}>
              {allSelected ? 'Deselect All' : 'Select All'}
            </button>
            <button
              type="button"
              className="revision-pill-btn revision-pill-btn--primary"
              disabled={included.size === 0 || busy}
              onClick={handleSubmitClick}
            >
              {busy ? 'Submitting…' : 'Submit Changes'}
            </button>
          </div>
        </div>
      </div>
    </ModalPortal>
  );
}
