import { useEffect, useMemo, useState } from "react";
import SectionCard from "../components/SectionCard";
import { api, downloadBinary, openBinary } from "../lib/api";
import { useLocation } from "react-router-dom";



const decisionStatusOptions = [
  { value: "in_bearbeitung", label: "In Bearbeitung" },
  { value: "rueckfrage", label: "Rückfrage" },
  { value: "abgeschlossen", label: "Abgeschlossen" },
];

function initialForm() {
  return {
    agenda_item_id: "",
    meeting_id: "",
    case_id: "",
    title: "",
    decision_text: "",
    status: "in_bearbeitung",
    votes_yes: "0",
    votes_no: "0",
    votes_abstain: "0",
    responsible_user_id: "",
    due_date: "",
  };
}

function normalizeDecisionStatus(value) {
  return decisionStatusOptions.some((item) => item.value === value) ? value : "in_bearbeitung";
}

function mapDecisionToForm(row) {
  return {
    agenda_item_id: row.agenda_item_id ? String(row.agenda_item_id) : "",
    meeting_id: row.meeting_id ? String(row.meeting_id) : "",
    case_id: row.case_id ? String(row.case_id) : "",
    title: row.title ?? "",
    decision_text: row.decision_text ?? "",
    status: normalizeDecisionStatus(row.status),
    votes_yes: String(row.votes_yes ?? 0),
    votes_no: String(row.votes_no ?? 0),
    votes_abstain: String(row.votes_abstain ?? 0),
    responsible_user_id: row.responsible_user_id ? String(row.responsible_user_id) : "",
    due_date: row.due_date ? String(row.due_date).slice(0, 16) : "",
  };
}

function normalizeAttachmentRow(row) {
  return {
    id: row.id,
    title: row.title || row.file_name || row.original_filename || "Datei",
    file_name: row.file_name || row.original_filename || row.title || "Datei",
    size_bytes: row.size_bytes || 0,
    mime_type: row.mime_type || "",
    uploaded_at: row.uploaded_at || row.created_at || null,
    uploaded_by_name: row.uploaded_by_name || "",
    uploaded_by_email: row.uploaded_by_email || "",
  };
}

function canPreviewAttachment(file) {
  const mime = String(file?.mime_type || "").toLowerCase();
  return mime.startsWith("image/") || mime === "application/pdf" || mime.startsWith("text/");
}

function formatFileSize(bytes) {
  const size = Number(bytes || 0);
  if (!size) return "0 KB";
  if (size < 1024) return `${size} B`;
  if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`;
  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
}

function formatDateTime(value) {
  if (!value) return "";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "";
  return date.toLocaleString("de-DE");
}

export default function DecisionsPage() {
  const [rows, setRows] = useState([]);
  const [meta, setMeta] = useState({ agendaItems: [], users: [] });
  const [selected, setSelected] = useState(null);
  const [form, setForm] = useState(initialForm());
  const [query, setQuery] = useState("");
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [isCanceling, setIsCanceling] = useState(false);
  const [autoCreatedDecisionId, setAutoCreatedDecisionId] = useState("");
  const [linkedCase, setLinkedCase] = useState(null);
  const [caseAttachments, setCaseAttachments] = useState([]);
  const [loadingCaseAssets, setLoadingCaseAssets] = useState(false);
  const [isVoteModalOpen, setIsVoteModalOpen] = useState(false);
  const [votingState, setVotingState] = useState(null);
  const [votingLoading, setVotingLoading] = useState(false);
  const [votingSubmitting, setVotingSubmitting] = useState(false);
  const [votingError, setVotingError] = useState("");
  const location = useLocation();

useEffect(() => {
  const openId = new URLSearchParams(location.search).get("open");
  if (!openId || !rows.length) return;

  const row = rows.find((item) => String(item.id) === String(openId));
  if (row) {
    openEditModal(row);
  }
}, [location.search, rows]);


  async function load() {
    setError("");
    try {
      const [decisions, metaData] = await Promise.all([api.get("/decisions"), api.get("/decisions/meta")]);
      setRows(Array.isArray(decisions) ? decisions : []);
      setMeta(metaData || { agendaItems: [], users: [] });
    } catch (err) {
      setError(err.message || "Daten konnten nicht geladen werden.");
    }
  }

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

  const filtered = useMemo(() => {
    const visibleRows = rows.filter((row) => row.status !== "abgeschlossen");
    const q = query.trim().toLowerCase();
    if (!q) return visibleRows;
    return visibleRows.filter((row) => JSON.stringify(row).toLowerCase().includes(q));
  }, [rows, query]);

  async function loadLinkedCaseAssets(caseId) {
    if (!caseId) {
      setLinkedCase(null);
      setCaseAttachments([]);
      return;
    }

    setLoadingCaseAssets(true);
    try {
      const [caseRow, attachments] = await Promise.all([
        api.get(`/cases/${caseId}`),
        api.get(`/cases/${caseId}/attachments`),
      ]);

      setLinkedCase(caseRow || null);
      const items = Array.isArray(attachments)
        ? attachments
        : Array.isArray(attachments?.items)
          ? attachments.items
          : [];
      setCaseAttachments(items.map(normalizeAttachmentRow));
    } catch (err) {
      setLinkedCase(null);
      setCaseAttachments([]);
      setError(err.message || "Vorgangsdateien konnten nicht geladen werden.");
    } finally {
      setLoadingCaseAssets(false);
    }
  }

  useEffect(() => {
    if (!isModalOpen) return;
    if (!form.case_id) {
      setLinkedCase(null);
      setCaseAttachments([]);
      return;
    }

    loadLinkedCaseAssets(form.case_id);
  }, [isModalOpen, form.case_id]);

  useEffect(() => {
    if (!isVoteModalOpen) return undefined;
    const decisionId = selected?.id || votingState?.decision?.id;
    if (!decisionId) return undefined;

    const timer = window.setInterval(() => {
      loadVotingState(decisionId, { silent: true });
    }, 2500);

    return () => window.clearInterval(timer);
  }, [isVoteModalOpen, selected?.id, votingState?.decision?.id]);

  function openCreateModal() {
    setSelected(null);
    setForm(initialForm());
    setLinkedCase(null);
    setCaseAttachments([]);
    setVotingState(null);
    setVotingError("");
    setAutoCreatedDecisionId("");
    setIsCanceling(false);
    setError("");
    setMessage("");
    setIsModalOpen(true);
  }

  function openEditModal(row) {
    setSelected(row);
    setAutoCreatedDecisionId("");
    setIsCanceling(false);
    setForm(mapDecisionToForm(row));
    setLinkedCase(row.case_id
      ? {
          id: row.case_id,
          case_number: row.case_number,
          title: row.title,
        }
      : null);
    setCaseAttachments([]);
    setVotingState(null);
    setVotingError("");
    setError("");
    setMessage("");
    setIsModalOpen(true);
  }

  function closeModal() {
    setIsModalOpen(false);
    setSelected(null);
    setForm(initialForm());
    setLinkedCase(null);
    setCaseAttachments([]);
    setLoadingCaseAssets(false);
    setIsVoteModalOpen(false);
    setVotingState(null);
    setVotingError("");
    setAutoCreatedDecisionId("");
    setIsCanceling(false);
  }

  async function cancelModal() {
    if (!autoCreatedDecisionId) {
      closeModal();
      return;
    }

    setIsCanceling(true);
    setError("");
    setVotingError("");

    try {
      await api.delete("/decisions/" + autoCreatedDecisionId);
      await load();
      closeModal();
      setMessage("Vorläufig angelegter Beschluss wurde verworfen.");
    } catch (err) {
      setError(err.message || "Vorläufig angelegter Beschluss konnte nicht gelöscht werden.");
      setIsCanceling(false);
    }
  }

  function handleAgendaChange(value) {
    const agenda = meta.agendaItems.find((row) => String(row.id) === String(value));
    setForm((prev) => ({
      ...prev,
      agenda_item_id: value,
      meeting_id: agenda?.meeting_id ? String(agenda.meeting_id) : "",
      case_id: agenda?.case_id ? String(agenda.case_id) : "",
      title: prev.title || agenda?.title || "",
    }));
  }

  async function viewAttachment(file) {
    try {
      await openBinary(`/documents/${file.id}/view`);
    } catch (err) {
      setError(err.message || "Datei konnte nicht angezeigt werden.");
    }
  }

  async function downloadAttachment(file) {
    try {
      await downloadBinary(`/documents/${file.id}/download`, file.file_name || file.title || `datei-${file.id}`);
    } catch (err) {
      setError(err.message || "Datei konnte nicht heruntergeladen werden.");
    }
  }

  function buildDecisionPayload() {
    const payload = {
      agenda_item_id: form.agenda_item_id ? Number(form.agenda_item_id) : null,
      meeting_id: form.meeting_id ? Number(form.meeting_id) : null,
      case_id: form.case_id ? Number(form.case_id) : null,
      title: form.title.trim(),
      decision_text: form.decision_text.trim(),
      status: form.status,
      votes_yes: Number(form.votes_yes || 0),
      votes_no: Number(form.votes_no || 0),
      votes_abstain: Number(form.votes_abstain || 0),
      responsible_user_id: form.responsible_user_id ? Number(form.responsible_user_id) : null,
      due_date: form.due_date || null,
    };

    if (!payload.title) {
      throw new Error("Bitte einen Titel eingeben.");
    }

    if (!payload.decision_text) {
      throw new Error("Bitte einen Beschlusstext eingeben.");
    }

    return payload;
  }

  function applyVotingState(state) {
    if (!state) return;
    setVotingState(state);

    const yes = String(state.counts?.yes ?? state.decision?.votes_yes ?? 0);
    const no = String(state.counts?.no ?? state.decision?.votes_no ?? 0);
    const abstain = String(state.counts?.abstain ?? state.decision?.votes_abstain ?? 0);

    setForm((prev) => ({
      ...prev,
      votes_yes: yes,
      votes_no: no,
      votes_abstain: abstain,
    }));

    if (state.decision?.id) {
      setRows((prev) => prev.map((row) => (
        String(row.id) === String(state.decision.id)
          ? {
              ...row,
              votes_yes: Number(yes),
              votes_no: Number(no),
              votes_abstain: Number(abstain),
              voting_open: state.decision.voting_open,
            }
          : row
      )));
    }
  }

  async function loadVotingState(decisionId, { silent = false } = {}) {
    if (!decisionId) return null;
    if (!silent) {
      setVotingLoading(true);
      setVotingError("");
    }

    try {
      const state = await api.get(`/decisions/${decisionId}/voting`);
      applyVotingState(state);
      return state;
    } catch (err) {
      if (!silent) setVotingError(err.message || "Abstimmung konnte nicht geladen werden.");
      return null;
    } finally {
      if (!silent) setVotingLoading(false);
    }
  }

  async function saveDecision({ keepModalOpen = false } = {}) {
    setError("");
    setMessage("");
    const payload = buildDecisionPayload();
    setIsSaving(true);

    try {
      let saved;
      if (selected?.id) {
        saved = await api.put(`/decisions/${selected.id}`, payload);
        setMessage("Beschluss gespeichert");
      } else {
        saved = await api.post("/decisions", payload);
        setMessage("Beschluss erstellt");
      }

      setSelected(saved);
      setForm(mapDecisionToForm(saved));
      await load();

      if (!keepModalOpen) closeModal();
      return saved;
    } catch (err) {
      setError(err.message || "Speichern fehlgeschlagen.");
      throw err;
    } finally {
      setIsSaving(false);
    }
  }

  async function submit(e) {
    e.preventDefault();
    try {
      await saveDecision({ keepModalOpen: false });
    } catch {
      // Fehlermeldung wird in saveDecision gesetzt.
    }
  }

  async function openVoteModal() {
    setError("");
    setVotingError("");

    try {
      let decision = selected;
      const createdForVoting = !decision?.id;
      if (createdForVoting) {
        decision = await saveDecision({ keepModalOpen: true });
        setAutoCreatedDecisionId(String(decision.id));
      }

      setIsVoteModalOpen(true);
      let state = await loadVotingState(decision.id);
      if (state?.can_manage && !state?.decision?.voting_open) {
        state = await api.post(`/decisions/${decision.id}/voting/start`, {});
        applyVotingState(state);
      }
    } catch (err) {
      setVotingError(err.message || "Abstimmung konnte nicht geöffnet werden.");
    }
  }

  async function startVoting() {
    const decisionId = selected?.id || votingState?.decision?.id;
    if (!decisionId) return;
    setVotingSubmitting(true);
    setVotingError("");
    try {
      const state = await api.post(`/decisions/${decisionId}/voting/start`, {});
      applyVotingState(state);
    } catch (err) {
      setVotingError(err.message || "Abstimmung konnte nicht gestartet werden.");
    } finally {
      setVotingSubmitting(false);
    }
  }

  async function closeVoting() {
    const decisionId = selected?.id || votingState?.decision?.id;
    if (!decisionId) return;
    setVotingSubmitting(true);
    setVotingError("");
    try {
      const state = await api.post(`/decisions/${decisionId}/voting/close`, {});
      applyVotingState(state);
    } catch (err) {
      setVotingError(err.message || "Abstimmung konnte nicht geschlossen werden.");
    } finally {
      setVotingSubmitting(false);
    }
  }

  async function castVote(voteValue) {
    const decisionId = selected?.id || votingState?.decision?.id;
    if (!decisionId) return;
    setVotingSubmitting(true);
    setVotingError("");
    try {
      const state = await api.put(`/decisions/${decisionId}/vote`, { vote_value: voteValue });
      applyVotingState(state);
    } catch (err) {
      setVotingError(err.message || "Stimme konnte nicht gespeichert werden.");
    } finally {
      setVotingSubmitting(false);
    }
  }

  async function removeItem(id) {
    setError("");
    setMessage("");
    try {
      await api.delete(`/decisions/${id}`);
      if (selected?.id === id) closeModal();
      await load();
      setMessage("Beschluss gelöscht");
    } catch (err) {
      setError(err.message || "Löschen fehlgeschlagen.");
    }
  }

  return (
    <>
      <style>{`
        .decisions-toolbar {
          display: flex;
          gap: 12px;
          align-items: center;
          justify-content: space-between;
          flex-wrap: wrap;
        }

        .row-actions {
          display: flex;
          gap: 8px;
          flex-wrap: wrap;
        }

        .modal-backdrop {
          position: fixed;
          inset: 0;
          background: rgba(15, 23, 42, 0.55);
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 16px;
          z-index: 1000;
        }

        .modal-panel {
          width: min(1100px, 100%);
          max-height: 92vh;
          overflow: auto;
          border-radius: 18px;
          background: rgba(255, 255, 255, 0.74);
          backdrop-filter: blur(18px);
          -webkit-backdrop-filter: blur(18px);
          border: 1px solid rgba(255, 255, 255, 0.24);
          box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
          padding: 18px;
        }

        .modal-header {
          display: flex;
          align-items: flex-start;
          justify-content: space-between;
          gap: 16px;
          margin-bottom: 16px;
        }

        .modal-subtitle {
          margin: 6px 0 0;
          opacity: 0.75;
          font-size: 0.95rem;
        }

        .modal-close {
          border: 0;
          background: transparent;
          font-size: 28px;
          line-height: 1;
          cursor: pointer;
          padding: 4px 8px;
        }

        .form-grid {
          display: grid;
          grid-template-columns: repeat(2, minmax(0, 1fr));
          gap: 14px;
        }

        .form-grid > label.full,
        .form-grid > div.full {
          grid-column: 1 / -1;
        }

        .helper-text {
          margin-top: 6px;
          font-size: 0.9rem;
          opacity: 0.75;
        }

        .attachments-section {
          display: grid;
          gap: 10px;
          margin-top: 6px;
        }

        .attachments-title {
          font-weight: 600;
        }

        .upload-list {
          list-style: none;
          margin: 0;
          padding: 0;
          display: grid;
          gap: 8px;
        }

        .upload-item {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 12px;
          padding: 10px 12px;
          border: 1px solid rgba(148, 163, 184, 0.35);
          border-radius: 12px;
          background: rgba(148, 163, 184, 0.08);
        }

        .upload-item-main {
          min-width: 0;
        }

        .upload-item-name {
          font-weight: 600;
          word-break: break-word;
        }

        .upload-item-meta {
          margin-top: 3px;
          font-size: 0.85rem;
          opacity: 0.75;
        }


        .vote-summary-card {
          grid-column: 1 / -1;
          border: 1px solid rgba(44, 107, 237, 0.18);
          border-radius: 16px;
          padding: 14px;
          background: rgba(44, 107, 237, 0.06);
          display: grid;
          gap: 12px;
        }

        .vote-summary-head {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 12px;
          flex-wrap: wrap;
        }

        .vote-summary-grid,
        .vote-count-row {
          display: grid;
          grid-template-columns: repeat(4, minmax(0, 1fr));
          gap: 10px;
        }

        .vote-summary-item {
          border: 1px solid rgba(148, 163, 184, 0.32);
          border-radius: 14px;
          background: rgba(255, 255, 255, 0.72);
          padding: 10px;
        }

        .vote-summary-item span {
          display: block;
          font-size: 0.82rem;
          color: var(--muted);
          margin-bottom: 4px;
        }

        .vote-summary-item strong {
          font-size: 1.2rem;
        }

        .vote-modal-backdrop {
          position: fixed;
          inset: 0;
          z-index: 1100;
          display: grid;
          place-items: center;
          padding: 20px;
          background: rgba(15, 23, 42, 0.62);
        }

        .vote-modal-panel {
          width: min(760px, 96vw);
          max-height: min(92vh, 920px);
          overflow: auto;
          border-radius: 22px;
          background: #ffffff;
          color: #0f172a;
          border: 1px solid rgba(15, 23, 42, 0.12);
          box-shadow: 0 30px 90px rgba(15, 23, 42, 0.34), 0 8px 24px rgba(15, 23, 42, 0.18);
          padding: 22px;
        }

        .vote-modal-header {
          display: flex;
          justify-content: space-between;
          align-items: flex-start;
          gap: 14px;
          margin-bottom: 14px;
        }

        .vote-status {
          display: inline-block;
          border-radius: 999px;
          padding: 4px 10px;
          font-weight: 700;
          font-size: 0.84rem;
          background: rgba(148, 163, 184, 0.16);
        }

        .vote-status.open {
          color: #047857;
          background: rgba(16, 185, 129, 0.12);
        }

        .vote-status.closed {
          color: #b45309;
          background: rgba(245, 158, 11, 0.14);
        }

        .vote-self-actions {
          display: flex;
          gap: 10px;
          flex-wrap: wrap;
          margin: 14px 0;
        }

        .vote-choice {
          border: 1px solid rgba(148, 163, 184, 0.35);
          border-radius: 999px;
          background: #ffffff;
          cursor: pointer;
          padding: 9px 14px;
          font-weight: 700;
        }

        .vote-choice.active {
          border-color: rgba(44, 107, 237, 0.65);
          background: rgba(44, 107, 237, 0.12);
          color: #1d4ed8;
        }

        .vote-list {
          display: grid;
          gap: 8px;
          margin-top: 12px;
        }

        .vote-row {
          display: flex;
          justify-content: space-between;
          align-items: center;
          gap: 12px;
          padding: 10px 12px;
          border-radius: 14px;
          border: 1px solid rgba(148, 163, 184, 0.28);
          background: #f8fafc;
        }

        .vote-user-meta {
          color: #64748b;
          font-size: 0.86rem;
          margin-top: 2px;
        }

        .vote-pill {
          border-radius: 999px;
          padding: 4px 9px;
          background: rgba(148, 163, 184, 0.16);
          font-weight: 700;
          white-space: nowrap;
        }

        @media (max-width: 860px) {
          .form-grid,
          .vote-summary-grid,
          .vote-count-row {
            grid-template-columns: 1fr;
          }

          .modal-panel {
            padding: 14px;
          }
        }
      `}</style>

      <div className="page-grid">
        <SectionCard
          title="Beschlüsse"
          subtitle="TOPs aus gestarteten Sitzungen stehen als Dropdown zur Verfügung. Sitzung und Vorgang werden daraus automatisch übernommen. Abgeschlossene Beschlüsse sind in dieser Liste ausgeblendet."
          actions={
            <div className="decisions-toolbar">
              <input
                className="input search"
                placeholder="Suchen..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
              />
              <button className="btn" type="button" onClick={openCreateModal}>
                Neuer Beschluss
              </button>
            </div>
          }
        >
          {error ? <div className="alert error">{error}</div> : null}
          {message ? <div className="alert success">{message}</div> : null}
          <div className="table-wrap">
            <table className="table">
              <thead>
                <tr>
                  <th>ID</th>
                  <th>Beschluss</th>
                  <th>TOP</th>
                  <th>Sitzung</th>
                  <th>Vorgang</th>
                  <th>Status</th>
                  <th>Aktionen</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map((row) => (
                  <tr key={row.id} onClick={() => openEditModal(row)}>
                    <td>{row.id}</td>
                    <td>{row.decision_number}</td>
                    <td>{row.agenda_number ? `${row.agenda_number} – ${row.agenda_title || ""}` : row.agenda_item_id || ""}</td>
                    <td>{row.meeting_number || row.meeting_id || ""}</td>
                    <td>{row.case_number || row.case_id || ""}</td>
                    <td>{decisionStatusOptions.find((item) => item.value === row.status)?.label || row.status}</td>
                    <td className="row-actions">
                      <button
                        className="mini-btn"
                        type="button"
                        onClick={(e) => {
                          e.stopPropagation();
                          openEditModal(row);
                        }}
                      >
                        Bearbeiten
                      </button>
                      <button
                        className="mini-btn danger"
                        type="button"
                        onClick={(e) => {
                          e.stopPropagation();
                          removeItem(row.id);
                        }}
                      >
                        Löschen
                      </button>
                    </td>
                  </tr>
                ))}
                {filtered.length === 0 ? (
                  <tr>
                    <td colSpan="7">Keine Beschlüsse gefunden.</td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </div>
        </SectionCard>
      </div>

      {isModalOpen ? (
        <div className="modal-backdrop" onClick={cancelModal}>
          <div className="modal-panel" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div>
                <h2 style={{ margin: 0 }}>{selected ? "Beschluss bearbeiten" : "Neuen Beschluss anlegen"}</h2>
                <p className="modal-subtitle">
                  Beschlussnummer wird automatisch vergeben. Wenn der gewählte TOP zu einem Vorgang gehört, wird dieser automatisch übernommen.
                </p>
              </div>
              <button className="modal-close" type="button" onClick={cancelModal} aria-label="Schließen" disabled={isCanceling}>
                ×
              </button>
            </div>

            {error ? <div className="alert error">{error}</div> : null}

            <form className="form-grid" onSubmit={submit}>
              <label>
                <span>Beschlussnummer</span>
                <input className="input" value={selected?.decision_number || "wird automatisch vergeben"} disabled />
              </label>

              <label>
                <span>TOP aus gestarteter Sitzung</span>
                <select className="input" value={form.agenda_item_id} onChange={(e) => handleAgendaChange(e.target.value)}>
                  <option value="">Bitte auswählen</option>
                  {meta.agendaItems.map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.meeting_number} · TOP {item.agenda_number} · {item.case_number ? `${item.case_number} · ` : ""}
                      {item.title}
                    </option>
                  ))}
                </select>
              </label>

              <label>
                <span>Sitzungs-ID</span>
                <input className="input" value={form.meeting_id} readOnly />
              </label>

              <label>
                <span>Vorgangs-ID</span>
                <input className="input" value={form.case_id} readOnly />
                <div className="helper-text">
                  {linkedCase?.case_number ? `Verknüpfter Vorgang: ${linkedCase.case_number}` : "Kein Vorgang aus dem TOP übernommen."}
                </div>
              </label>

              <label className="full">
                <span>Titel</span>
                <input className="input" value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} />
              </label>

              <label>
                <span>Status</span>
                <select className="input" value={form.status} onChange={(e) => setForm({ ...form, status: e.target.value })}>
                  {decisionStatusOptions.map((item) => (
                    <option key={item.value} value={item.value}>
                      {item.label}
                    </option>
                  ))}
                </select>
              </label>

              <label>
                <span>Verantwortliche Person</span>
                <select
                  className="input"
                  value={form.responsible_user_id}
                  onChange={(e) => setForm({ ...form, responsible_user_id: e.target.value })}
                >
                  <option value="">Bitte auswählen</option>
                  {meta.users.map((user) => (
                    <option key={user.id} value={user.id}>
                      {user.full_name} ({user.email})
                    </option>
                  ))}
                </select>
              </label>

              <div className="full vote-summary-card">
                <div className="vote-summary-head">
                  <div>
                    <strong>Abstimmung</strong>
                    <div className="helper-text">
                      Mitglieder des Gremiums der ausgewählten Sitzung stimmen selbst ab. Die Summen werden vom Server gezählt und hier automatisch übernommen.
                    </div>
                  </div>
                  <button className="btn secondary" type="button" onClick={openVoteModal} disabled={isSaving || isCanceling}>
                    {selected?.id ? "Abstimmung öffnen" : "Speichern & Abstimmung"}
                  </button>
                </div>

                <div className="vote-summary-grid">
                  <div className="vote-summary-item"><span>Ja</span><strong>{form.votes_yes || 0}</strong></div>
                  <div className="vote-summary-item"><span>Nein</span><strong>{form.votes_no || 0}</strong></div>
                  <div className="vote-summary-item"><span>Enthaltung</span><strong>{form.votes_abstain || 0}</strong></div>
                  <div className="vote-summary-item"><span>Gesamt</span><strong>{Number(form.votes_yes || 0) + Number(form.votes_no || 0) + Number(form.votes_abstain || 0)}</strong></div>
                </div>
              </div>

              <label>
                <span>Ja-Stimmen</span>
                <input
                  className="input"
                  type="number"
                  min="0"
                  value={form.votes_yes}
                  onChange={(e) => setForm({ ...form, votes_yes: e.target.value })}
                />
              </label>

              <label>
                <span>Nein-Stimmen</span>
                <input
                  className="input"
                  type="number"
                  min="0"
                  value={form.votes_no}
                  onChange={(e) => setForm({ ...form, votes_no: e.target.value })}
                />
              </label>

              <label>
                <span>Enthaltungen</span>
                <input
                  className="input"
                  type="number"
                  min="0"
                  value={form.votes_abstain}
                  onChange={(e) => setForm({ ...form, votes_abstain: e.target.value })}
                />
              </label>

              <label>
                <span>Umsetzungsfrist</span>
                <input
                  className="input"
                  type="datetime-local"
                  value={form.due_date}
                  onChange={(e) => setForm({ ...form, due_date: e.target.value })}
                />
              </label>

              <label className="full">
                <span>Beschlusstext</span>
                <textarea
                  className="input textarea"
                  value={form.decision_text}
                  onChange={(e) => setForm({ ...form, decision_text: e.target.value })}
                />
              </label>

              <div className="full">
                <span>Vorgangsdateien</span>
                <div className="attachments-section">
                  {!form.case_id ? <div className="helper-text">Kein verknüpfter Vorgang vorhanden.</div> : null}
                  {form.case_id && loadingCaseAssets ? <div className="helper-text">Vorgangsdateien werden geladen...</div> : null}
                  {form.case_id && !loadingCaseAssets && linkedCase?.title ? (
                    <div className="helper-text">
                      {linkedCase.case_number ? `${linkedCase.case_number} – ` : ""}
                      {linkedCase.title}
                    </div>
                  ) : null}
                  {form.case_id && !loadingCaseAssets && caseAttachments.length === 0 ? (
                    <div className="helper-text">Zu diesem Vorgang sind keine Dateien vorhanden.</div>
                  ) : null}
                  {caseAttachments.length > 0 ? (
                    <ul className="upload-list">
                      {caseAttachments.map((file) => (
                        <li key={file.id} className="upload-item">
                          <div className="upload-item-main">
                            <div className="upload-item-name">{file.file_name}</div>
                            <div className="upload-item-meta">{formatFileSize(file.size_bytes)}</div>
                            {file.uploaded_at ? <div className="upload-item-meta">Hochgeladen: {formatDateTime(file.uploaded_at)}</div> : null}
                            {file.uploaded_by_name ? <div className="upload-item-meta">Von: {file.uploaded_by_name}</div> : null}
                          </div>
                          <div className="row-actions">
                            {canPreviewAttachment(file) ? (
                              <button
                                type="button"
                                className="mini-btn"
                                onClick={() => viewAttachment(file)}
                              >
                                Anzeigen
                              </button>
                            ) : null}
                            <button
                              type="button"
                              className="mini-btn"
                              onClick={() => downloadAttachment(file)}
                            >
                              Download
                            </button>
                          </div>
                        </li>
                      ))}
                    </ul>
                  ) : null}
                </div>
              </div>

              <div className="full" style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
                <button className="btn" type="submit" disabled={isSaving || isCanceling}>
                  {isSaving ? "Speichern..." : selected ? "Speichern" : "Erstellen"}
                </button>
                <button className="btn secondary" type="button" onClick={cancelModal} disabled={isSaving || isCanceling}>
                  {isCanceling ? "Verwerfe..." : "Abbrechen"}
                </button>
                {autoCreatedDecisionId ? (
                  <div className="helper-text" style={{ flexBasis: "100%" }}>
                    Dieser Beschluss wurde für die Abstimmung vorläufig gespeichert. Beim Abbrechen wird er wieder gelöscht.
                  </div>
                ) : null}
              </div>
            </form>
          </div>
        </div>
      ) : null}
      {isVoteModalOpen ? (
        <div className="vote-modal-backdrop" onClick={() => setIsVoteModalOpen(false)}>
          <div className="vote-modal-panel" role="dialog" aria-modal="true" onClick={(e) => e.stopPropagation()}>
            <div className="vote-modal-header">
              <div>
                <h2 style={{ margin: 0 }}>Abstimmung</h2>
                <p className="modal-subtitle">
                  {votingState?.decision?.decision_number ? `${votingState.decision.decision_number} – ` : ""}
                  {votingState?.decision?.title || form.title}
                </p>
                <p className="modal-subtitle">
                  {votingState?.decision?.committee_name ? `Gremium: ${votingState.decision.committee_name}` : "Kein Gremium zugeordnet"}
                  {votingState?.decision?.meeting_number ? ` · Sitzung: ${votingState.decision.meeting_number}` : ""}
                </p>
              </div>
              <button className="modal-close" type="button" onClick={() => setIsVoteModalOpen(false)} aria-label="Schließen">
                ×
              </button>
            </div>

            {votingError ? <div className="alert error">{votingError}</div> : null}
            {votingLoading ? <div className="helper-text">Abstimmung wird geladen...</div> : null}

            <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", marginBottom: 14 }}>
              <span className={`vote-status ${votingState?.decision?.voting_open ? "open" : "closed"}`}>
                {votingState?.decision?.voting_open ? "Abstimmung geöffnet" : "Abstimmung geschlossen"}
              </span>
              <span className="helper-text">
                Stimmberechtigte: {votingState?.eligible_voter_count ?? 0} · Abgegeben: {votingState?.total_votes ?? 0}
              </span>
            </div>

            <div className="vote-count-row">
              <div className="vote-summary-item"><span>Ja</span><strong>{votingState?.counts?.yes ?? form.votes_yes ?? 0}</strong></div>
              <div className="vote-summary-item"><span>Nein</span><strong>{votingState?.counts?.no ?? form.votes_no ?? 0}</strong></div>
              <div className="vote-summary-item"><span>Enthaltung</span><strong>{votingState?.counts?.abstain ?? form.votes_abstain ?? 0}</strong></div>
              <div className="vote-summary-item"><span>Gesamt</span><strong>{votingState?.total_votes ?? 0}</strong></div>
            </div>

            <div className="vote-self-actions">
              <button
                className={`vote-choice ${votingState?.current_user_vote === "yes" ? "active" : ""}`}
                type="button"
                disabled={votingSubmitting || !votingState?.decision?.voting_open || !votingState?.current_user_can_vote}
                onClick={() => castVote("yes")}
              >
                Ja
              </button>
              <button
                className={`vote-choice ${votingState?.current_user_vote === "no" ? "active" : ""}`}
                type="button"
                disabled={votingSubmitting || !votingState?.decision?.voting_open || !votingState?.current_user_can_vote}
                onClick={() => castVote("no")}
              >
                Nein
              </button>
              <button
                className={`vote-choice ${votingState?.current_user_vote === "abstain" ? "active" : ""}`}
                type="button"
                disabled={votingSubmitting || !votingState?.decision?.voting_open || !votingState?.current_user_can_vote}
                onClick={() => castVote("abstain")}
              >
                Enthaltung
              </button>
            </div>

            {!votingState?.current_user_can_vote ? (
              <div className="helper-text">
                Du bist für dieses Gremium nicht stimmberechtigt oder die Sitzung ist nicht gestartet.
              </div>
            ) : null}

            {votingState?.can_manage ? (
              <div className="row-actions" style={{ margin: "14px 0" }}>
                {!votingState?.decision?.voting_open ? (
                  <button className="btn" type="button" onClick={startVoting} disabled={votingSubmitting}>
                    Abstimmung starten
                  </button>
                ) : (
                  <button className="btn secondary" type="button" onClick={closeVoting} disabled={votingSubmitting}>
                    Abstimmung schließen
                  </button>
                )}
                <button
                  className="btn secondary"
                  type="button"
                  onClick={() => loadVotingState(selected?.id || votingState?.decision?.id)}
                  disabled={votingLoading || votingSubmitting}
                >
                  Aktualisieren
                </button>
              </div>
            ) : null}

            <div className="vote-list">
              {(votingState?.eligible_voters || []).map((voter) => (
                <div className="vote-row" key={voter.id}>
                  <div>
                    <strong>{voter.full_name || voter.email || `Benutzer ${voter.id}`}</strong>
                    <div className="vote-user-meta">
                      {voter.email || "ohne E-Mail"}{voter.voted_at ? ` · ${formatDateTime(voter.voted_at)}` : ""}
                    </div>
                  </div>
                  <span className="vote-pill">
                    {voter.vote_value === "yes" ? "Ja" : voter.vote_value === "no" ? "Nein" : voter.vote_value === "abstain" ? "Enthaltung" : "offen"}
                  </span>
                </div>
              ))}
              {votingState && !(votingState.eligible_voters || []).length ? (
                <div className="helper-text">Keine stimmberechtigten Mitglieder für dieses Gremium gefunden.</div>
              ) : null}
            </div>
          </div>
        </div>
      ) : null}

    </>
  );
}
