import { useEffect, useMemo, useState } from "react";
import SectionCard from "../components/SectionCard";
import { api } from "../lib/api";

const statusOptions = [
  { value: "offen", label: "Offen" },
  { value: "in_bearbeitung", label: "In Bearbeitung" },
  { value: "wartet", label: "Wartet" },
  { value: "erledigt", label: "Erledigt" },
  { value: "abgebrochen", label: "Abgebrochen" },
];

const priorityOptions = [
  { value: "sehr_hoch", label: "Sehr hoch" },
  { value: "hoch", label: "Hoch" },
  { value: "mittel", label: "Mittel" },
  { value: "niedrig", label: "Niedrig" },
];

const confidentialityOptions = [
  { value: "intern", label: "Intern" },
  { value: "vertraulich", label: "Vertraulich" },
  { value: "streng_vertraulich", label: "Streng vertraulich" },
];

function initialForm() {
  return {
    title: "",
    description: "",
    status: "offen",
    priority: "mittel",
    assigned_user_id: "",
    backup_user_id: "",
    committee_id: "",
    case_id: "",
    meeting_id: "",
    agenda_item_id: "",
    decision_id: "",
    due_date: "",
    confidentiality_level: "intern",
  };
}

function asString(value) {
  if (value === null || value === undefined) return "";
  return String(value);
}

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

function normalizeTaskForm(row) {
  return {
    title: row.title ?? "",
    description: row.description ?? "",
    status: row.status ?? "offen",
    priority: row.priority ?? "mittel",
    assigned_user_id: row.assigned_user_id ? String(row.assigned_user_id) : "",
    backup_user_id: row.backup_user_id ? String(row.backup_user_id) : "",
    committee_id: row.committee_id ? String(row.committee_id) : "",
    case_id: row.case_id ? String(row.case_id) : "",
    meeting_id: row.meeting_id ? String(row.meeting_id) : "",
    agenda_item_id: row.agenda_item_id ? String(row.agenda_item_id) : "",
    decision_id: row.decision_id ? String(row.decision_id) : "",
    due_date: row.due_date ? String(row.due_date).slice(0, 16) : "",
    confidentiality_level: row.confidentiality_level ?? "intern",
  };
}

function TaskFormModal({
  open,
  selected,
  form,
  setForm,
  users,
  committees,
  meetings,
  agendaItems,
  decisions,
  cases,
  startedMeeting,
  onClose,
  onSubmit,
  loading,
  error,
}) {
  if (!open) return null;

  const startedMeetingAgendaItems = startedMeeting
    ? agendaItems.filter((row) => String(row.meeting_id || "") === String(startedMeeting.id))
    : [];

  const agendaItemsForMeeting = form.meeting_id
    ? agendaItems.filter((row) => String(row.meeting_id || "") === String(form.meeting_id))
    : [];

  const visibleDecisions = decisions.filter((row) => {
    if (form.meeting_id && String(row.meeting_id || "") === String(form.meeting_id)) return true;
    if (form.case_id && String(row.case_id || "") === String(form.case_id)) return true;
    if (form.decision_id && String(row.id) === String(form.decision_id)) return true;
    return !form.meeting_id && !form.case_id;
  });

  function applyStartedMeeting() {
    if (!startedMeeting) return;

    const firstTop = startedMeetingAgendaItems[0] || null;

    setForm((prev) => ({
      ...prev,
      meeting_id: String(startedMeeting.id),
      agenda_item_id: firstTop?.id ? String(firstTop.id) : prev.agenda_item_id,
      case_id: firstTop?.case_id ? String(firstTop.case_id) : prev.case_id,
      decision_id: firstTop?.decision_id ? String(firstTop.decision_id) : prev.decision_id,
    }));
  }

  function handleMeetingChange(value) {
    const firstTop = agendaItems.find((row) => String(row.meeting_id || "") === String(value)) || null;

    setForm((prev) => ({
      ...prev,
      meeting_id: value,
      agenda_item_id: firstTop?.id ? String(firstTop.id) : "",
      case_id: firstTop?.case_id ? String(firstTop.case_id) : prev.case_id,
      decision_id: firstTop?.decision_id ? String(firstTop.decision_id) : prev.decision_id,
    }));
  }

  function handleAgendaItemChange(value) {
    const item = agendaItems.find((row) => String(row.id) === String(value));
    if (!item) {
      setForm((prev) => ({ ...prev, agenda_item_id: "" }));
      return;
    }

    setForm((prev) => ({
      ...prev,
      agenda_item_id: String(item.id),
      meeting_id: item.meeting_id ? String(item.meeting_id) : prev.meeting_id,
      case_id: item.case_id ? String(item.case_id) : prev.case_id,
      decision_id: item.decision_id ? String(item.decision_id) : prev.decision_id,
    }));
  }

  function handleDecisionChange(value) {
    const decision = decisions.find((row) => String(row.id) === String(value));

    setForm((prev) => ({
      ...prev,
      decision_id: value,
      case_id: decision?.case_id ? String(decision.case_id) : prev.case_id,
      meeting_id: decision?.meeting_id ? String(decision.meeting_id) : prev.meeting_id,
    }));
  }

  function caseLabel(caseId) {
    const row = cases.find((item) => String(item.id) === String(caseId));
    return row ? `${row.case_number || row.id} – ${row.title || ""}` : caseId || "Wird automatisch übernommen";
  }

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal-panel" onClick={(e) => e.stopPropagation()}>
        <div className="modal-header">
          <div>
            <h2 style={{ margin: 0 }}>{selected ? "Aufgabe bearbeiten" : "Neue Aufgabe anlegen"}</h2>
            <p className="modal-subtitle">
              Status, Priorität, Vertraulichkeit und Zuordnungen werden vollständig im Modal gepflegt.
            </p>
          </div>
          <button className="modal-close" type="button" onClick={onClose} aria-label="Schließen">
            ×
          </button>
        </div>

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

        <form className="form-grid" onSubmit={onSubmit}>
          <div className="row-actions" style={{ gridColumn: "1 / -1", marginBottom: 4 }}>
            <button
              className="btn secondary"
              type="button"
              onClick={applyStartedMeeting}
              disabled={!startedMeeting}
            >
              Gestartete Sitzung übernehmen
            </button>
            {startedMeeting ? (
              <span className="field-hint">
                Aktiv: {startedMeeting.meeting_number || startedMeeting.id}
                {startedMeeting.title ? ` – ${startedMeeting.title}` : ""}
              </span>
            ) : (
              <span className="field-hint">Keine gestartete Sitzung gefunden.</span>
            )}
          </div>

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

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

          <label>
            <span>Priorität</span>
            <select
              className="input"
              value={form.priority}
              onChange={(e) => setForm((prev) => ({ ...prev, priority: e.target.value }))}
            >
              {priorityOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>

          <label>
            <span>Vertraulichkeit</span>
            <select
              className="input"
              value={form.confidentiality_level}
              onChange={(e) =>
                setForm((prev) => ({ ...prev, confidentiality_level: e.target.value }))
              }
            >
              {confidentialityOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>

          <label>
            <span>Sitzung</span>
            <select
              className="input"
              value={form.meeting_id}
              onChange={(e) => handleMeetingChange(e.target.value)}
            >
              <option value="">Keine Sitzung</option>
              {meetings.map((meeting) => (
                <option key={meeting.id} value={meeting.id}>
                  {meeting.meeting_number || meeting.id}
                  {meeting.title ? ` – ${meeting.title}` : ""}
                  {meeting.status ? ` (${meeting.status})` : ""}
                </option>
              ))}
            </select>
          </label>

          <label>
            <span>TOP aus aktiver/gewählter Sitzung</span>
            <select
              className="input"
              value={form.agenda_item_id}
              onChange={(e) => handleAgendaItemChange(e.target.value)}
            >
              <option value="">Kein TOP</option>
              {agendaItemsForMeeting.map((item) => (
                <option key={item.id} value={item.id}>
                  {item.title}
                  {item.case_number ? ` – ${item.case_number}` : item.case_id ? ` – Vorgang ${item.case_id}` : ""}
                </option>
              ))}
            </select>
          </label>

          <label>
            <span>Beschluss</span>
            <select
              className="input"
              value={form.decision_id}
              onChange={(e) => handleDecisionChange(e.target.value)}
            >
              <option value="">Kein Beschluss</option>
              {visibleDecisions.map((decision) => (
                <option key={decision.id} value={decision.id}>
                  {decision.title || `Beschluss ${decision.id}`}
                </option>
              ))}
            </select>
            <div className="field-hint">
              Beim Speichern wird die Aufgabe mit dem gewählten TOP und optionalem Beschluss verknüpft.
            </div>
          </label>

          <label>
            <span>Vorgang</span>
            <input className="input" value={caseLabel(form.case_id)} readOnly />
            <div className="field-hint">
              Wird aus TOP, Beschluss oder gestarteter Sitzung übernommen.
            </div>
          </label>

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

          <label>
            <span>Primär zugewiesen an</span>
            <select
              className="input"
              value={form.assigned_user_id}
              onChange={(e) => setForm((prev) => ({ ...prev, assigned_user_id: e.target.value }))}
            >
              <option value="">Kein Benutzer</option>
              {users.map((user) => (
                <option key={user.id} value={user.id}>
                  {user.full_name}
                </option>
              ))}
            </select>
          </label>

          <label>
            <span>Stellvertretung</span>
            <select
              className="input"
              value={form.backup_user_id}
              onChange={(e) => setForm((prev) => ({ ...prev, backup_user_id: e.target.value }))}
            >
              <option value="">Keine Stellvertretung</option>
              {users.map((user) => (
                <option key={user.id} value={user.id}>
                  {user.full_name}
                </option>
              ))}
            </select>
            <div className="field-hint">
              Mehrfachzuweisung ist hier über primäre Zuweisung, Stellvertretung und optionales Gremium abgebildet.
            </div>
          </label>

          <label>
            <span>Gremium</span>
            <select
              className="input"
              value={form.committee_id}
              onChange={(e) => setForm((prev) => ({ ...prev, committee_id: e.target.value }))}
            >
              <option value="">Kein Gremium</option>
              {committees.map((committee) => (
                <option key={committee.id} value={committee.id}>
                  {committee.name}
                </option>
              ))}
            </select>
          </label>

          <label style={{ gridColumn: "1 / -1" }}>
            <span>Beschreibung</span>
            <textarea
              className="input textarea"
              style={{ minHeight: 200 }}
              value={form.description}
              onChange={(e) => setForm((prev) => ({ ...prev, description: e.target.value }))}
            />
          </label>

          <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, gridColumn: "1 / -1" }}>
            <button className="btn secondary" type="button" onClick={onClose}>
              Abbrechen
            </button>
            <button className="btn" type="submit" disabled={loading}>
              {loading ? "Speichern..." : selected ? "Speichern" : "Erstellen"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default function TasksPage() {
  const [rows, setRows] = useState([]);
  const [users, setUsers] = useState([]);
  const [committees, setCommittees] = useState([]);
  const [meetings, setMeetings] = useState([]);
  const [agendaItems, setAgendaItems] = useState([]);
  const [decisions, setDecisions] = useState([]);
  const [cases, setCases] = useState([]);

  const [selected, setSelected] = useState(null);
  const [form, setForm] = useState(initialForm());

  const [query, setQuery] = useState("");
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");
  const [modalError, setModalError] = useState("");
  const [loading, setLoading] = useState(false);
  const [deletingId, setDeletingId] = useState(null);
  const [isModalOpen, setIsModalOpen] = useState(false);

  const startedMeeting = useMemo(
    () => meetings.find((row) => String(row.status || "").toLowerCase() === "gestartet") || null,
    [meetings]
  );

  const usersById = useMemo(
    () => Object.fromEntries(users.map((row) => [String(row.id), row])),
    [users]
  );

  const committeesById = useMemo(
    () => Object.fromEntries(committees.map((row) => [String(row.id), row])),
    [committees]
  );

  const meetingsById = useMemo(
    () => Object.fromEntries(meetings.map((row) => [String(row.id), row])),
    [meetings]
  );

  const casesById = useMemo(
    () => Object.fromEntries(cases.map((row) => [String(row.id), row])),
    [cases]
  );

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

  async function load() {
    setError("");

    const [
      tasksResult,
      usersResult,
      committeesResult,
      meetingsResult,
      agendaItemsResult,
      decisionsResult,
      casesResult,
    ] = await Promise.allSettled([
      api.get("/tasks"),
      api.get("/users"),
      api.get("/committees"),
      api.get("/meetings"),
      api.get("/agenda-items?include_assigned=true"),
      api.get("/decisions"),
      api.get("/cases"),
    ]);

    if (tasksResult.status === "fulfilled") {
      setRows(Array.isArray(tasksResult.value) ? tasksResult.value : []);
    } else {
      setError(tasksResult.reason?.message || "Aufgaben konnten nicht geladen werden.");
    }

    setUsers(
      usersResult.status === "fulfilled" && Array.isArray(usersResult.value)
        ? usersResult.value.filter((row) => row.is_active !== false)
        : []
    );
    setCommittees(
      committeesResult.status === "fulfilled" && Array.isArray(committeesResult.value)
        ? committeesResult.value
        : []
    );
    setMeetings(
      meetingsResult.status === "fulfilled" && Array.isArray(meetingsResult.value)
        ? meetingsResult.value
        : []
    );
    setAgendaItems(
      agendaItemsResult.status === "fulfilled" && Array.isArray(agendaItemsResult.value)
        ? agendaItemsResult.value
        : []
    );
    setDecisions(
      decisionsResult.status === "fulfilled" && Array.isArray(decisionsResult.value)
        ? decisionsResult.value
        : []
    );
    setCases(
      casesResult.status === "fulfilled" && Array.isArray(casesResult.value)
        ? casesResult.value
        : []
    );
  }

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

  function openCreateModal() {
    const next = initialForm();

    if (startedMeeting) {
      next.meeting_id = String(startedMeeting.id);
      const firstTop =
        agendaItems.find((row) => String(row.meeting_id || "") === String(startedMeeting.id)) || null;

      if (firstTop) {
        next.agenda_item_id = firstTop.id ? String(firstTop.id) : "";
        next.case_id = firstTop.case_id ? String(firstTop.case_id) : "";
        next.decision_id = firstTop.decision_id ? String(firstTop.decision_id) : "";
      }
    }

    setSelected(null);
    setForm(next);
    setModalError("");
    setMessage("");
    setError("");
    setIsModalOpen(true);
  }

  function openEditModal(row) {
    setSelected(row);
    setForm(normalizeTaskForm(row));
    setModalError("");
    setMessage("");
    setError("");
    setIsModalOpen(true);
  }

  function closeModal() {
    setSelected(null);
    setForm(initialForm());
    setModalError("");
    setIsModalOpen(false);
  }

  async function submit(e) {
    e.preventDefault();
    setModalError("");
    setMessage("");

    if (!form.title.trim()) {
      setModalError("Bitte einen Titel eingeben.");
      return;
    }

    setLoading(true);

    try {
      const payload = {
        title: form.title.trim(),
        description: form.description.trim() || null,
        status: form.status,
        priority: form.priority,
        assigned_user_id: form.assigned_user_id ? Number(form.assigned_user_id) : null,
        backup_user_id: form.backup_user_id ? Number(form.backup_user_id) : null,
        case_id: form.case_id ? Number(form.case_id) : null,
        meeting_id: form.meeting_id ? Number(form.meeting_id) : null,
        agenda_item_id: form.agenda_item_id ? Number(form.agenda_item_id) : null,
        decision_id: form.decision_id ? Number(form.decision_id) : null,
        due_date: form.due_date || null,
        confidentiality_level: form.confidentiality_level,
        committee_id: form.committee_id ? Number(form.committee_id) : null, // entfernen, falls dein Backend dieses Feld noch nicht kennt
      };

      if (selected?.id) {
        await api.put(`/tasks/${selected.id}`, payload);
        setMessage("Aufgabe gespeichert");
      } else {
        await api.post("/tasks", payload);
        setMessage("Aufgabe erstellt");
      }

      await load();
      closeModal();
    } catch (err) {
      setModalError(err.message || "Aufgabe konnte nicht gespeichert werden.");
    } finally {
      setLoading(false);
    }
  }

  async function removeItem(row) {
    setError("");
    setMessage("");
    setDeletingId(row.id);

    try {
      await api.delete(`/tasks/${row.id}`);
      if (selected?.id === row.id) closeModal();
      await load();
      setMessage("Aufgabe gelöscht");
    } catch (err) {
      setError(err.message || "Aufgabe konnte nicht gelöscht werden.");
    } finally {
      setDeletingId(null);
    }
  }

  return (
    <>
      <style>{`
        .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(1040px, 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;
        }
      `}</style>

      <SectionCard
        title="Aufgaben"
        subtitle="Aufgaben werden im Modal angelegt und können direkt mit gestarteter Sitzung, TOP, Beschluss, Benutzern und Gremium verknüpft werden."
        actions={
          <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
            <input
              className="input search"
              placeholder="Suchen..."
              value={query}
              onChange={(e) => setQuery(e.target.value)}
            />
            <button className="btn" type="button" onClick={openCreateModal}>
              Neue Aufgabe
            </button>
          </div>
        }
      >
        {error ? <div className="alert error">{error}</div> : null}
        {message ? <div className="alert success">{message}</div> : null}

        {loading && !rows.length ? <div className="field-hint">Aufgaben werden geladen…</div> : null}

        <div className="table-wrap">
          <table className="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>Titel</th>
                <th>Status</th>
                <th>Priorität</th>
                <th>Fällig</th>
                <th>Sitzung</th>
                <th>Vorgang</th>
                <th>Benutzer/Gremium</th>
                <th>Vertraulichkeit</th>
                <th>Aktionen</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((row) => {
                const user = usersById[String(row.assigned_user_id || "")];
                const backupUser = usersById[String(row.backup_user_id || "")];
                const committee = committeesById[String(row.committee_id || "")];
                const meeting = meetingsById[String(row.meeting_id || "")];
                const taskCase = casesById[String(row.case_id || "")];

                return (
                  <tr key={row.id}>
                    <td>{row.id}</td>
                    <td>{row.title}</td>
                    <td>{statusOptions.find((item) => item.value === row.status)?.label || row.status}</td>
                    <td>{priorityOptions.find((item) => item.value === row.priority)?.label || row.priority}</td>
                    <td>{formatDateTime(row.due_date)}</td>
                    <td>
                      {meeting
                        ? `${meeting.meeting_number || meeting.id}${meeting.title ? ` – ${meeting.title}` : ""}`
                        : row.meeting_id || ""}
                    </td>
                    <td>
                      {taskCase
                        ? `${taskCase.case_number || taskCase.id}${taskCase.title ? ` – ${taskCase.title}` : ""}`
                        : row.case_number || row.case_id || ""}
                    </td>
                    <td>
                      {user?.full_name || ""}
                      {backupUser?.full_name ? ` / Stv. ${backupUser.full_name}` : ""}
                      {committee?.name ? ` / ${committee.name}` : ""}
                    </td>
                    <td>
                      {confidentialityOptions.find(
                        (item) => item.value === row.confidentiality_level
                      )?.label || row.confidentiality_level}
                    </td>
                    <td className="row-actions">
                      <button className="mini-btn" type="button" onClick={() => openEditModal(row)}>
                        Bearbeiten
                      </button>
                      <button
                        className="mini-btn danger"
                        type="button"
                        disabled={deletingId === row.id}
                        onClick={() => removeItem(row)}
                      >
                        Löschen
                      </button>
                    </td>
                  </tr>
                );
              })}
              {filtered.length === 0 ? (
                <tr>
                  <td colSpan={10}>Keine Aufgaben gefunden.</td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </SectionCard>

      <TaskFormModal
        open={isModalOpen}
        selected={selected}
        form={form}
        setForm={setForm}
        users={users}
        committees={committees}
        meetings={meetings}
        agendaItems={agendaItems}
        decisions={decisions}
        cases={cases}
        startedMeeting={startedMeeting}
        onClose={closeModal}
        onSubmit={submit}
        loading={loading}
        error={modalError}
      />
    </>
  );
}
