import { useEffect, useMemo, useState } from "react";
import SectionCard from "../components/SectionCard";
import { api, downloadBinary, openBinary } from "../lib/api";
import {
  Button,
  Dropdown,
  Field,
  Input,
  Option,
  Spinner,
  Textarea,
  makeStyles,
  tokens,
} from "@fluentui/react-components";
import {
  Add24Regular,
  ArrowDownload24Regular,
  Delete24Regular,
  Edit24Regular,
  Open24Regular,
} from "@fluentui/react-icons";

const statusOptions = [
  { value: "offen", label: "Offen" },
  { value: "in_bearbeitung", label: "In Bearbeitung" },
  { value: "erledigt", label: "Erledigt" },
  { value: "ueberfaellig", label: "Überfällig" },
];

const useStyles = makeStyles({
  toolbar: {
    display: "flex",
    gap: "12px",
    alignItems: "center",
    justifyContent: "space-between",
    flexWrap: "wrap",
  },
  search: {
    minWidth: "280px",
    flexGrow: 1,
  },
  formGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
    gap: "16px",
    alignItems: "start",
    "@media (max-width: 860px)": {
      gridTemplateColumns: "1fr",
    },
  },
  full: {
    gridColumn: "1 / -1",
  },
  helperText: {
    fontSize: tokens.fontSizeBase200,
    color: tokens.colorNeutralForeground3,
    marginTop: "6px",
  },
  tableWrap: {
    overflowX: "auto",
  },
  rowActions: {
    display: "flex",
    gap: "8px",
    flexWrap: "wrap",
  },
  attachmentHeader: {
    marginBottom: "8px",
    fontWeight: 600,
  },
  fluentInput: {
    backgroundColor: "rgba(255, 255, 255, 0.92)",
    borderRadius: "10px",
    border: "1px solid rgba(148, 163, 184, 0.35)",
    boxShadow: "none",
    "& input": {
      backgroundColor: "#FFFFFF",
      color: "#0f172a",
    },
  },
  fluentTextareaLarge: {
    backgroundColor: "rgba(255, 255, 255, 0.92)",
    borderRadius: "10px",
    border: "1px solid rgba(148, 163, 184, 0.35)",
    "& textarea": {
      backgroundColor: "#FFFFFF",
      color: "#0f172a",
      minHeight: "220px",
    },
  },
  fluentDropdown: {
    backgroundColor: "rgba(255, 255, 255, 0.92)",
    borderRadius: "10px",
    border: "1px solid rgba(148, 163, 184, 0.35)",
    color: "#0f172a",
  },
});

function initialForm() {
  return {
    case_id: "",
    title: "",
    deadline_type: "",
    due_date_date: null,
    due_date_time: "",
    status: "offen",
    remind_days_before: 3,
    assigned_user_id: "",
    committee_id: "",
    description: "",
  };
}

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 toDateParts(value) {
  if (!value) {
    return { date: null, time: "" };
  }

  const parsed = new Date(value);
  if (!Number.isNaN(parsed.getTime())) {
    return {
      date: new Date(parsed.getFullYear(), parsed.getMonth(), parsed.getDate()),
      time: `${String(parsed.getHours()).padStart(2, "0")}:${String(parsed.getMinutes()).padStart(2, "0")}`,
    };
  }

  const raw = String(value);
  const [datePart = "", timePart = ""] = raw.split("T");
  const [year, month, day] = datePart.split("-").map((x) => Number(x));
  const time = timePart.slice(0, 5);

  if (year && month && day) {
    return {
      date: new Date(year, month - 1, day),
      time,
    };
  }

  return { date: null, time: "" };
}

function combineDateTime(dateValue, timeValue) {
  if (!dateValue || !(dateValue instanceof Date) || Number.isNaN(dateValue.getTime())) {
    return null;
  }

  const [hoursRaw = "0", minutesRaw = "0"] = String(timeValue || "00:00").split(":");
  const hours = Number(hoursRaw || 0);
  const minutes = Number(minutesRaw || 0);

  const year = dateValue.getFullYear();
  const month = String(dateValue.getMonth() + 1).padStart(2, "0");
  const day = String(dateValue.getDate()).padStart(2, "0");
  const hh = String(hours).padStart(2, "0");
  const mm = String(minutes).padStart(2, "0");

  return `${year}-${month}-${day}T${hh}:${mm}`;
}

function mapDeadlineToForm(row) {
  const parts = toDateParts(row.due_date);

  return {
    case_id: row.case_id ? String(row.case_id) : "",
    title: row.title ?? "",
    deadline_type: row.deadline_type ?? "",
    due_date_date: parts.date,
    due_date_time: parts.time,
    status: row.status ?? "offen",
    remind_days_before:
      row.remind_days_before === null || row.remind_days_before === undefined
        ? 3
        : Number(row.remind_days_before),
    assigned_user_id: row.assigned_user_id ? String(row.assigned_user_id) : "",
    committee_id: row.committee_id ? String(row.committee_id) : "",
    description: row.description ?? "",
  };
}

function DeadlineFormFields({
  form,
  setForm,
  users,
  committees,
  attachments,
  pendingFiles,
  setPendingFiles,
  selected,
  onRemoveAttachment,
  onViewAttachment,
  onDownloadAttachment,
}) {
  const styles = useStyles();

  return (
    <div className={styles.formGrid}>
      <Field label="Vorgangs-ID">
        <Input
          className={styles.fluentInput}
          value={form.case_id || selected?.case_number || "wird automatisch vergeben"}
          disabled
        />
      </Field>

      <Field label="Titel" required>
        <Input
          className={styles.fluentInput}
          value={form.title}
          onChange={(_, data) => setForm((prev) => ({ ...prev, title: data.value }))}
        />
      </Field>

      <Field label="Fristart" required>
        <Input
          className={styles.fluentInput}
          value={form.deadline_type}
          onChange={(_, data) => setForm((prev) => ({ ...prev, deadline_type: data.value }))}
        />
      </Field>

      <Field label="Fällig am" required>
        <Input
          className={styles.fluentInput}
          type="date"
          value={
            form.due_date_date instanceof Date && !Number.isNaN(form.due_date_date.getTime())
              ? [
                  form.due_date_date.getFullYear(),
                  String(form.due_date_date.getMonth() + 1).padStart(2, "0"),
                  String(form.due_date_date.getDate()).padStart(2, "0"),
                ].join("-")
              : ""
          }
          onChange={(_, data) => {
            const value = data.value;
            if (!value) {
              setForm((prev) => ({ ...prev, due_date_date: null }));
              return;
            }

            const [year, month, day] = value.split("-").map(Number);
            const nextDate = new Date(year, (month || 1) - 1, day || 1);
            setForm((prev) => ({ ...prev, due_date_date: nextDate }));
          }}
        />
      </Field>

      <Field label="Uhrzeit">
        <Input
          className={styles.fluentInput}
          type="time"
          value={form.due_date_time || ""}
          onChange={(_, data) =>
            setForm((prev) => ({
              ...prev,
              due_date_time: data.value || "",
            }))
          }
        />
      </Field>

      <Field label="Status">
        <Dropdown
          className={styles.fluentDropdown}
          selectedOptions={[form.status]}
          value={statusOptions.find((item) => item.value === form.status)?.label || ""}
          onOptionSelect={(_, data) =>
            setForm((prev) => ({ ...prev, status: data.optionValue || "offen" }))
          }
        >
          {statusOptions.map((option) => (
            <Option key={option.value} value={option.value}>
              {option.label}
            </Option>
          ))}
        </Dropdown>
      </Field>

      <Field label="Erinnerung Tage vorher">
        <Input
          className={styles.fluentInput}
          type="number"
          min="0"
          value={String(form.remind_days_before ?? "")}
          onChange={(_, data) =>
            setForm((prev) => ({
              ...prev,
              remind_days_before: data.value === "" ? "" : Number(data.value),
            }))
          }
        />
      </Field>

      <Field label="Zugewiesener Benutzer">
        <Dropdown
          className={styles.fluentDropdown}
          selectedOptions={[form.assigned_user_id || "__none__"]}
          value={
            form.assigned_user_id
              ? users.find((user) => String(user.id) === String(form.assigned_user_id))?.full_name || ""
              : "Kein Benutzer"
          }
          onOptionSelect={(_, data) =>
            setForm((prev) => ({
              ...prev,
              assigned_user_id: data.optionValue === "__none__" ? "" : String(data.optionValue || ""),
            }))
          }
        >
          <Option value="__none__">Kein Benutzer</Option>
          {users.map((user) => (
            <Option key={user.id} value={String(user.id)}>
              {user.full_name} {user.email ? `(${user.email})` : ""}
            </Option>
          ))}
        </Dropdown>
      </Field>

      <Field label="Gremium">
        <Dropdown
          className={styles.fluentDropdown}
          selectedOptions={[form.committee_id || "__none__"]}
          value={
            form.committee_id
              ? committees.find((committee) => String(committee.id) === String(form.committee_id))?.name || ""
              : "Kein Gremium"
          }
          onOptionSelect={(_, data) =>
            setForm((prev) => ({
              ...prev,
              committee_id: data.optionValue === "__none__" ? "" : String(data.optionValue || ""),
            }))
          }
        >
          <Option value="__none__">Kein Gremium</Option>
          {committees.map((committee) => (
            <Option key={committee.id} value={String(committee.id)}>
              {committee.name}
            </Option>
          ))}
        </Dropdown>
      </Field>

      <div className={styles.full}>
        <Field label="Beschreibung">
          <Textarea
            className={styles.fluentTextareaLarge}
            value={form.description}
            resize="vertical"
            onChange={(_, data) => setForm((prev) => ({ ...prev, description: data.value }))}
          />
        </Field>
      </div>

      <div className={styles.full}>
        <Field label="Dokumente anhängen">
          <Input
            className={styles.fluentInput}
            type="file"
            multiple
            onChange={(e) => setPendingFiles(Array.from(e.target.files || []))}
          />
        </Field>
        {pendingFiles.length ? (
          <div className={styles.helperText}>
            Ausgewählt: {pendingFiles.map((file) => file.name).join(", ")}
          </div>
        ) : null}
      </div>

      {selected ? (
        <div className={styles.full}>
          <div className={styles.attachmentHeader}>Vorhandene Anhänge</div>
          <div className={styles.tableWrap}>
            <table className="table">
              <thead>
                <tr>
                  <th>ID</th>
                  <th>Datei</th>
                  <th>Hochgeladen</th>
                  <th>Aktionen</th>
                </tr>
              </thead>
              <tbody>
                {attachments.map((row) => (
                  <tr key={row.id}>
                    <td>{row.id}</td>
                    <td>{row.file_name || row.title || ""}</td>
                    <td>{formatDateTime(row.uploaded_at)}</td>
                    <td>
                      <div className={styles.rowActions}>
                        <Button
                          appearance="secondary"
                          size="small"
                          icon={<Open24Regular />}
                          onClick={() => onViewAttachment(row)}
                        >
                          Anzeigen
                        </Button>
                        <Button
                          appearance="secondary"
                          size="small"
                          icon={<ArrowDownload24Regular />}
                          onClick={() => onDownloadAttachment(row)}
                        >
                          Download
                        </Button>
                        <Button
                          appearance="secondary"
                          size="small"
                          icon={<Delete24Regular />}
                          onClick={() => onRemoveAttachment(row)}
                        >
                          Entfernen
                        </Button>
                      </div>
                    </td>
                  </tr>
                ))}
                {!attachments.length ? (
                  <tr>
                    <td colSpan={4}>Keine Anhänge vorhanden</td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </div>
        </div>
      ) : null}
    </div>
  );
}

function DeadlineModal({
  open,
  selected,
  form,
  setForm,
  users,
  committees,
  attachments,
  pendingFiles,
  setPendingFiles,
  loading,
  error,
  onClose,
  onSubmit,
  onRemoveAttachment,
  onViewAttachment,
  onDownloadAttachment,
}) {
  if (!open) return null;

  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 ? "Frist bearbeiten" : "Neue Frist anlegen"}</h2>
            <p className="modal-subtitle">
              Vorgangs-ID wird nicht mehr manuell gepflegt und nur noch angezeigt.
            </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 onSubmit={onSubmit}>
          <DeadlineFormFields
            form={form}
            setForm={setForm}
            users={users}
            committees={committees}
            attachments={attachments}
            pendingFiles={pendingFiles}
            setPendingFiles={setPendingFiles}
            selected={selected}
            onRemoveAttachment={onRemoveAttachment}
            onViewAttachment={onViewAttachment}
            onDownloadAttachment={onDownloadAttachment}
          />

          <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, marginTop: 20 }}>
            <Button appearance="secondary" onClick={onClose}>
              Abbrechen
            </Button>
            <Button appearance="primary" type="submit" disabled={loading}>
              {loading ? "Speichern..." : selected ? "Speichern" : "Erstellen"}
            </Button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default function DeadlinesPage() {
  const styles = useStyles();

  const [rows, setRows] = useState([]);
  const [users, setUsers] = useState([]);
  const [committees, setCommittees] = useState([]);
  const [attachments, setAttachments] = useState([]);
  const [pendingFiles, setPendingFiles] = 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);

  async function load() {
    setError("");
    try {
      const [deadlines, userData, committeeData] = await Promise.all([
        api.get("/deadlines"),
        api.get("/users"),
        api.get("/committees"),
      ]);

      setRows(Array.isArray(deadlines) ? deadlines : []);
      setUsers(Array.isArray(userData) ? userData.filter((row) => row.is_active !== false) : []);
      setCommittees(Array.isArray(committeeData) ? committeeData : []);
    } catch (err) {
      setError(err.message || "Fristen konnten nicht geladen werden.");
    }
  }

  async function loadAttachments(deadlineId) {
    try {
      const data = await api.get(`/deadlines/${deadlineId}/attachments`);
      setAttachments(Array.isArray(data) ? data : []);
    } catch {
      setAttachments([]);
    }
  }

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

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

  function openCreateModal() {
    setSelected(null);
    setForm(initialForm());
    setAttachments([]);
    setPendingFiles([]);
    setModalError("");
    setMessage("");
    setError("");
    setIsModalOpen(true);
  }

  async function openEditModal(row) {
    setSelected(row);
    setForm(mapDeadlineToForm(row));
    setPendingFiles([]);
    setModalError("");
    setMessage("");
    setError("");
    setIsModalOpen(true);
    await loadAttachments(row.id);
  }

  function closeModal() {
    setSelected(null);
    setForm(initialForm());
    setAttachments([]);
    setPendingFiles([]);
    setModalError("");
    setIsModalOpen(false);
  }

  async function uploadPendingFiles(deadlineId) {
    if (!pendingFiles.length) return;

    const fd = new FormData();
    pendingFiles.forEach((file) => fd.append("files", file));
    await api.post(`/deadlines/${deadlineId}/attachments`, fd);
  }

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

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

    if (!form.deadline_type.trim()) {
      setModalError("Bitte eine Fristart eingeben.");
      return;
    }

    if (!form.due_date_date) {
      setModalError("Bitte ein Datum auswählen.");
      return;
    }

    setLoading(true);

    try {
      const payload = {
        title: form.title.trim(),
        deadline_type: form.deadline_type.trim(),
        due_date: combineDateTime(form.due_date_date, form.due_date_time),
        status: form.status,
        remind_days_before:
          form.remind_days_before === "" || form.remind_days_before === null
            ? null
            : Number(form.remind_days_before),
        assigned_user_id: form.assigned_user_id ? Number(form.assigned_user_id) : null,
        committee_id: form.committee_id ? Number(form.committee_id) : null,
        description: form.description.trim() || null,
      };

      let deadlineId = selected?.id || null;

      if (selected?.id) {
        await api.put(`/deadlines/${selected.id}`, payload);
        setMessage("Frist gespeichert");
      } else {
        const created = await api.post("/deadlines", payload);
        deadlineId = created?.id || null;
        setMessage("Frist erstellt");
      }

      if (deadlineId && pendingFiles.length) {
        await uploadPendingFiles(deadlineId);
      }

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

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

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

  async function removeAttachment(row) {
    if (!selected?.id) return;

    setModalError("");
    try {
      await api.delete(`/deadlines/${selected.id}/attachments/${row.id}`);
      await loadAttachments(selected.id);
    } catch (err) {
      setModalError(err.message || "Anhang konnte nicht entfernt werden.");
    }
  }

  async function viewAttachment(row) {
    if (!selected?.id) return;
    try {
      await openBinary(`/deadlines/${selected.id}/attachments/${row.id}/view`);
    } catch (err) {
      setModalError(err.message || "Anhang konnte nicht angezeigt werden.");
    }
  }

  async function downloadAttachment(row) {
    if (!selected?.id) return;
    try {
      await downloadBinary(
        `/deadlines/${selected.id}/attachments/${row.id}/download`,
        row.file_name || `anhang-${row.id}`
      );
    } catch (err) {
      setModalError(err.message || "Anhang konnte nicht heruntergeladen werden.");
    }
  }

  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="Fristen"
        subtitle="Fristen werden über ein Dialogfenster angelegt, bearbeitet und verwaltet. Benutzer, Gremien und mehrere Dokumente können zugeordnet werden."
        actions={
          <div className={styles.toolbar}>
            <Input
              className={styles.search}
              placeholder="Suchen..."
              value={query}
              onChange={(_, data) => setQuery(data.value)}
            />
            <button className="btn" type="button" onClick={openCreateModal}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
                <Add24Regular />
                Neue Frist
              </span>
            </button>
          </div>
        }
      >
        {error ? <div className="alert error">{error}</div> : null}
        {message ? <div className="alert success">{message}</div> : null}

        {loading && !rows.length ? <Spinner label="Fristen werden geladen..." /> : null}

        <div className={styles.tableWrap}>
          <table className="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>Vorgang</th>
                <th>Titel</th>
                <th>Fristart</th>
                <th>Fällig</th>
                <th>Status</th>
                <th>Benutzer</th>
                <th>Gremium</th>
                <th>Aktionen</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((row) => (
                <tr key={row.id}>
                  <td>{row.id}</td>
                  <td>{row.case_number || row.case_id || ""}</td>
                  <td>{row.title}</td>
                  <td>{row.deadline_type}</td>
                  <td>{formatDateTime(row.due_date)}</td>
                  <td>{statusOptions.find((item) => item.value === row.status)?.label || row.status}</td>
                  <td>{row.assigned_user_name || row.assigned_user_id || ""}</td>
                  <td>{row.committee_name || row.committee_id || ""}</td>
                  <td>
                    <div className={styles.rowActions}>
                      <Button
                        appearance="secondary"
                        size="small"
                        icon={<Edit24Regular />}
                        onClick={() => openEditModal(row)}
                      >
                        Bearbeiten
                      </Button>
                      <Button
                        appearance="secondary"
                        size="small"
                        icon={<Delete24Regular />}
                        disabled={deletingId === row.id}
                        onClick={() => removeItem(row)}
                      >
                        Löschen
                      </Button>
                    </div>
                  </td>
                </tr>
              ))}
              {!filtered.length ? (
                <tr>
                  <td colSpan={9}>Keine Fristen vorhanden</td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </SectionCard>

      <DeadlineModal
        open={isModalOpen}
        selected={selected}
        form={form}
        setForm={setForm}
        users={users}
        committees={committees}
        attachments={attachments}
        pendingFiles={pendingFiles}
        setPendingFiles={setPendingFiles}
        loading={loading}
        error={modalError}
        onClose={closeModal}
        onSubmit={submit}
        onRemoveAttachment={removeAttachment}
        onViewAttachment={viewAttachment}
        onDownloadAttachment={downloadAttachment}
      />
    </>
  );
}
