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

export default function CrudPage({ title, subtitle, endpoint, columns, fields, fileUpload = false, detailHint }) {
  const [rows, setRows] = useState([]);
  const [form, setForm] = useState({});
  const [selected, setSelected] = useState(null);
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");
  const [query, setQuery] = useState("");

  async function load() {
    setError("");
    try {
      const data = await api.get(endpoint);
      setRows(Array.isArray(data) ? data : []);
    } catch (err) {
      setError(err.message);
    }
  }

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

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

  function choose(row) {
    setSelected(row);
    setForm(row);
    setMessage("");
    setError("");
  }

  function reset() {
    setSelected(null);
    setForm({});
  }

  async function submit(e) {
    e.preventDefault();
    setError("");
    setMessage("");
    try {
      if (fileUpload) {
        const fd = new FormData();
        Object.entries(form).forEach(([key, value]) => {
          if (value !== undefined && value !== null) fd.append(key, value);
        });
        await api.post(`${endpoint}/upload`, fd);
      } else if (selected?.id) {
        await api.post(`${endpoint.replace(/\/$/, "")}/${selected.id}`, form); // fallback for old backends
      }
      setMessage(selected?.id ? "Gespeichert" : "Erstellt");
      if (!fileUpload && selected?.id) {
        await fetchUpdate();
      } else if (!fileUpload && !selected?.id) {
        await api.post(endpoint, form);
      }
      await load();
      if (!fileUpload) reset();
    } catch (err) {
      // old backends may not support POST on /:id, so use PUT
      try {
        if (!fileUpload && selected?.id) {
          await fetch(`${(import.meta.env.VITE_API_BASE_URL || "http://localhost:8080/api")}${endpoint}/${selected.id}`, {
            method: "PUT",
            credentials: "include",
            headers: {
              "Content-Type": "application/json",
              Authorization: `Bearer ${window.__br_access_token || ""}`,
            },
            body: JSON.stringify(form),
          }).then(async (r) => {
            const j = await r.json().catch(() => ({}));
            if (!r.ok) throw new Error(j.error || "API-Fehler");
          });
          setMessage("Gespeichert");
          await load();
          reset();
          return;
        }
        if (!fileUpload && !selected?.id) {
          await api.post(endpoint, form);
          setMessage("Erstellt");
          await load();
          reset();
          return;
        }
      } catch (secondErr) {
        setError(secondErr.message);
        return;
      }
      setError(err.message);
    }
  }

  async function fetchUpdate() {
    await fetch(`${(import.meta.env.VITE_API_BASE_URL || "http://localhost:8080/api")}${endpoint}/${selected.id}`, {
      method: "PUT",
      credentials: "include",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${window.__br_access_token || ""}`,
      },
      body: JSON.stringify(form),
    }).then(async (r) => {
      const j = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(j.error || "API-Fehler");
    });
  }

  async function remove(id) {
    setError("");
    try {
      await fetch(`${(import.meta.env.VITE_API_BASE_URL || "http://localhost:8080/api")}${endpoint}/${id}`, {
        method: "DELETE",
        credentials: "include",
        headers: {
          Authorization: `Bearer ${window.__br_access_token || ""}`,
        }
      }).then(async (r) => {
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.error || "API-Fehler");
      });
      await load();
      if (selected?.id === id) reset();
    } catch (err) {
      setError(err.message);
    }
  }

  return (
    <div className="page-grid">
      <SectionCard title={title} subtitle={subtitle} actions={<input className="input search" placeholder="Suchen..." value={query} onChange={(e) => setQuery(e.target.value)} />}>
        {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>
                {columns.map((col) => <th key={col.key}>{col.label}</th>)}
                <th>Aktionen</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((row) => (
                <tr key={row.id} onClick={() => choose(row)}>
                  {columns.map((col) => <td key={col.key}>{String(row[col.key] ?? "")}</td>)}
                  <td className="row-actions">
                    <button className="mini-btn" onClick={(e) => { e.stopPropagation(); choose(row); }}>Bearbeiten</button>
                    <button className="mini-btn danger" onClick={(e) => { e.stopPropagation(); remove(row.id); }}>Löschen</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </SectionCard>
      <SectionCard title={selected ? "Datensatz bearbeiten" : "Neuen Datensatz anlegen"} subtitle={detailHint || "CRUD-Maske mit sicherem API-Backend und RLS-geschützter Datenhaltung."} actions={<button className="btn secondary" onClick={reset}>Zurücksetzen</button>}>
        <form className="form-grid" onSubmit={submit}>
          {fields.map((field) => (
            <label key={field.name}>
              <span>{field.label}</span>
              {field.type === "textarea" ? (
                <textarea className="input textarea" value={form[field.name] ?? ""} onChange={(e) => setForm({ ...form, [field.name]: e.target.value })} />
              ) : field.type === "file" ? (
                <input className="input" type="file" onChange={(e) => setForm({ ...form, [field.name]: e.target.files?.[0] })} />
              ) : field.type === "checkbox" ? (
                <input type="checkbox" checked={Boolean(form[field.name])} onChange={(e) => setForm({ ...form, [field.name]: e.target.checked })} />
              ) : (
                <input className="input" type={field.type || "text"} value={form[field.name] ?? ""} onChange={(e) => setForm({ ...form, [field.name]: e.target.value })} />
              )}
            </label>
          ))}
          <button className="btn" type="submit">{selected ? "Speichern" : "Erstellen"}</button>
        </form>
      </SectionCard>
    </div>
  );
}
