import React, { useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import { apiFetch } from "../api";
import { useAuth } from "../state";

const emptyForm = {
  name: "",
  host: "",
  port: 5432,
  dbname: "postgres",
  username: "",
  password: "",
  sslmode: "prefer",
  use_pg_stat_statements: true,
  discover_all_databases: false,
  owner_user_ids: [],
  tags: {},
};

const emptyEditForm = {
  id: null,
  name: "",
  host: "",
  port: 5432,
  dbname: "",
  username: "",
  password: "",
  sslmode: "prefer",
  use_pg_stat_statements: true,
  owner_user_ids: [],
};

function toggleOwner(ids, userId) {
  return ids.includes(userId) ? ids.filter((id) => id !== userId) : [...ids, userId];
}

function OwnerPicker({ candidates, selectedIds, onToggle, query, onQueryChange }) {
  const pickerRef = useRef(null);
  const [open, setOpen] = useState(false);
  const filtered = candidates.filter((item) =>
    item.email.toLowerCase().includes(query.trim().toLowerCase())
  );
  const selected = candidates.filter((item) => selectedIds.includes(item.user_id));

  useEffect(() => {
    const onPointerDown = (event) => {
      if (!pickerRef.current?.contains(event.target)) {
        setOpen(false);
      }
    };
    document.addEventListener("mousedown", onPointerDown);
    return () => document.removeEventListener("mousedown", onPointerDown);
  }, []);

  return (
    <div className="owner-picker" ref={pickerRef}>
      <div className="owner-selected">
        {selected.length > 0 ? (
          selected.map((item) => (
            <button
              key={`selected-${item.user_id}`}
              type="button"
              className="owner-selected-chip"
              onClick={() => onToggle(item.user_id)}
              title="Remove owner"
            >
              <span>{item.email}</span>
              <span aria-hidden="true">x</span>
            </button>
          ))
        ) : (
          <span className="muted">No owners selected yet.</span>
        )}
      </div>
      <div className={`owner-search-shell ${open ? "open" : ""}`}>
        <input
          type="text"
          className="owner-search-input"
          value={query}
          onChange={(e) => onQueryChange(e.target.value)}
          onFocus={() => setOpen(true)}
          onClick={() => setOpen(true)}
          placeholder="Search users by email..."
        />
        <button type="button" className="owner-search-toggle" onClick={() => setOpen((prev) => !prev)}>
          v
        </button>
      </div>
      {open && (
        <div className="owner-dropdown">
          <div className="owner-search-results">
            {filtered.map((item) => {
              const active = selectedIds.includes(item.user_id);
              return (
                <button
                  key={item.user_id}
                  type="button"
                  className={`owner-result ${active ? "active" : ""}`}
                  onClick={() => onToggle(item.user_id)}
                >
                  <span>{item.email}</span>
                  <small>{item.role}</small>
                </button>
              );
            })}
            {filtered.length === 0 && <div className="owner-result-empty">No matching users.</div>}
          </div>
        </div>
      )}
    </div>
  );
}

export function TargetsPage() {
  const { tokens, refresh, me } = useAuth();
  const [targets, setTargets] = useState([]);
  const [form, setForm] = useState(emptyForm);
  const [editForm, setEditForm] = useState(emptyEditForm);
  const [editing, setEditing] = useState(false);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);
  const [testState, setTestState] = useState({ loading: false, message: "", ok: null });
  const [saveState, setSaveState] = useState({ loading: false, message: "" });
  const [ownerCandidates, setOwnerCandidates] = useState([]);
  const [createOwnerQuery, setCreateOwnerQuery] = useState("");
  const [editOwnerQuery, setEditOwnerQuery] = useState("");

  const canManage = me?.role === "admin" || me?.role === "operator";

  const load = async () => {
    setLoading(true);
    try {
      if (canManage) {
        const [targetRows, candidates] = await Promise.all([
          apiFetch("/targets", {}, tokens, refresh),
          apiFetch("/targets/owner-candidates", {}, tokens, refresh),
        ]);
        setTargets(targetRows);
        setOwnerCandidates(candidates);
      } else {
        setTargets(await apiFetch("/targets", {}, tokens, refresh));
      }
      setError("");
    } catch (e) {
      setError(String(e.message || e));
    } finally {
      setLoading(false);
    }
  };

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

  const createTarget = async (e) => {
    e.preventDefault();
    try {
      await apiFetch("/targets", { method: "POST", body: JSON.stringify(form) }, tokens, refresh);
      setForm(emptyForm);
      await load();
    } catch (e) {
      setError(String(e.message || e));
    }
  };

  const testConnection = async () => {
    setTestState({ loading: true, message: "", ok: null });
    try {
      const result = await apiFetch(
        "/targets/test-connection",
        {
          method: "POST",
          body: JSON.stringify({
            host: form.host,
            port: form.port,
            dbname: form.dbname,
            username: form.username,
            password: form.password,
            sslmode: form.sslmode,
          }),
        },
        tokens,
        refresh
      );
      setTestState({ loading: false, message: `${result.message} (PostgreSQL ${result.server_version})`, ok: true });
    } catch (e) {
      setTestState({ loading: false, message: String(e.message || e), ok: false });
    }
  };

  const deleteTarget = async (id) => {
    if (!confirm("Delete target?")) return;
    try {
      await apiFetch(`/targets/${id}`, { method: "DELETE" }, tokens, refresh);
      await load();
    } catch (e) {
      setError(String(e.message || e));
    }
  };

  const startEdit = (target) => {
    setEditing(true);
    setSaveState({ loading: false, message: "" });
    setEditOwnerQuery("");
    setEditForm({
      id: target.id,
      name: target.name,
      host: target.host,
      port: target.port,
      dbname: target.dbname,
      username: target.username,
      password: "",
      sslmode: target.sslmode,
      use_pg_stat_statements: target.use_pg_stat_statements !== false,
      owner_user_ids: Array.isArray(target.owner_user_ids) ? target.owner_user_ids : [],
    });
  };

  const cancelEdit = () => {
    setEditing(false);
    setEditForm(emptyEditForm);
    setSaveState({ loading: false, message: "" });
  };

  const saveEdit = async (e) => {
    e.preventDefault();
    if (!editForm.id) return;
    setSaveState({ loading: true, message: "" });
    try {
      const payload = {
        name: editForm.name,
        host: editForm.host,
        port: Number(editForm.port),
        dbname: editForm.dbname,
        username: editForm.username,
        sslmode: editForm.sslmode,
        use_pg_stat_statements: !!editForm.use_pg_stat_statements,
        owner_user_ids: editForm.owner_user_ids || [],
      };
      if (editForm.password.trim()) payload.password = editForm.password;

      await apiFetch(`/targets/${editForm.id}`, { method: "PUT", body: JSON.stringify(payload) }, tokens, refresh);
      setSaveState({ loading: false, message: "Target updated." });
      setEditing(false);
      setEditForm(emptyEditForm);
      await load();
    } catch (e) {
      setSaveState({ loading: false, message: String(e.message || e) });
    }
  };

  return (
    <div className="targets-page">
      <h2>Targets Management</h2>
      {error && <div className="card error">{error}</div>}

      {canManage && (
        <details className="card collapsible">
          <summary className="collapse-head">
            <div>
              <h3>New Target</h3>
            </div>
            <span className="collapse-chevron" aria-hidden="true">v</span>
          </summary>

          <form className="target-form grid two" onSubmit={createTarget}>
            <div className="field">
              <label>Name</label>
              <input placeholder="e.g. Prod-DB" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} required />
            </div>
            <div className="field">
              <label>Host</label>
              <input placeholder="e.g. 172.16.0.106 or db.internal" value={form.host} onChange={(e) => setForm({ ...form, host: e.target.value })} required />
            </div>
            <div className="field">
              <label>Port</label>
              <input placeholder="5432" value={form.port} onChange={(e) => setForm({ ...form, port: Number(e.target.value) })} type="number" required />
            </div>
            <div className="field">
              <label>{form.discover_all_databases ? "Discovery DB" : "DB Name"}</label>
              <input
                placeholder={form.discover_all_databases ? "e.g. postgres" : "e.g. postgres or appdb"}
                value={form.dbname}
                onChange={(e) => setForm({ ...form, dbname: e.target.value })}
                required
              />
              <small>
                {form.discover_all_databases
                  ? "Connection database used to crawl all available databases on this instance."
                  : "Single database to monitor for this target."}
              </small>
            </div>
            <div className="field">
              <label>Username</label>
              <input placeholder="e.g. postgres" value={form.username} onChange={(e) => setForm({ ...form, username: e.target.value })} required />
            </div>
            <div className="field">
              <label>Password</label>
              <input placeholder="Password" type="password" value={form.password} onChange={(e) => setForm({ ...form, password: e.target.value })} required />
            </div>
            <div className="field">
              <label>SSL Mode</label>
              <select value={form.sslmode} onChange={(e) => setForm({ ...form, sslmode: e.target.value })}>
                <option value="disable">disable</option>
                <option value="prefer">prefer</option>
                <option value="require">require</option>
              </select>
              <small>
                If you see "rejected SSL upgrade", switch to <code>disable</code>.
              </small>
            </div>
            <div className="field toggle-field">
              <label>Query Insights Source</label>
              <label className="toggle-check">
                <input
                  type="checkbox"
                  checked={!!form.use_pg_stat_statements}
                  onChange={(e) => setForm({ ...form, use_pg_stat_statements: e.target.checked })}
                />
                <span className="toggle-ui" aria-hidden="true" />
                <span className="toggle-copy">
                  <strong>Use pg_stat_statements for this target</strong>
                  <small>Disable this if the extension is unavailable on the target.</small>
                </span>
              </label>
            </div>
            <div className="field toggle-field">
              <label>Scope</label>
              <label className="toggle-check">
                <input
                  type="checkbox"
                  checked={!!form.discover_all_databases}
                  onChange={(e) => setForm({ ...form, discover_all_databases: e.target.checked })}
                />
                <span className="toggle-ui" aria-hidden="true" />
                <span className="toggle-copy">
                  <strong>Discover and add all databases</strong>
                  <small>Requires credentials with access to list databases (typically a superuser).</small>
                </span>
              </label>
            </div>
            <div className="field field-full">
              <label>Responsible Users (Target Owners)</label>
              <OwnerPicker
                candidates={ownerCandidates}
                selectedIds={form.owner_user_ids}
                query={createOwnerQuery}
                onQueryChange={setCreateOwnerQuery}
                onToggle={(userId) => setForm({ ...form, owner_user_ids: toggleOwner(form.owner_user_ids, userId) })}
              />
              <small>Only selected users will receive email notifications for this target's alerts.</small>
            </div>
            <div className="field submit-field field-full">
              <div className="form-actions">
                <button type="button" className="secondary-btn" onClick={testConnection} disabled={testState.loading}>
                  {testState.loading ? "Testing..." : "Test connection"}
                </button>
                <button className="primary-btn">Create target</button>
              </div>
            </div>
          </form>
          {testState.message && (
            <div className={`test-connection-result ${testState.ok ? "ok" : "fail"}`}>{testState.message}</div>
          )}
        </details>
      )}

      {canManage && editing && (
        <section className="card">
          <h3>Edit Target</h3>
          <form className="target-form grid two" onSubmit={saveEdit}>
            <div className="field">
              <label>Name</label>
              <input value={editForm.name} onChange={(e) => setEditForm({ ...editForm, name: e.target.value })} required />
            </div>
            <div className="field">
              <label>Host</label>
              <input value={editForm.host} onChange={(e) => setEditForm({ ...editForm, host: e.target.value })} required />
            </div>
            <div className="field">
              <label>Port</label>
              <input type="number" value={editForm.port} onChange={(e) => setEditForm({ ...editForm, port: Number(e.target.value) })} required />
            </div>
            <div className="field">
              <label>DB Name</label>
              <input value={editForm.dbname} onChange={(e) => setEditForm({ ...editForm, dbname: e.target.value })} required />
            </div>
            <div className="field">
              <label>Username</label>
              <input value={editForm.username} onChange={(e) => setEditForm({ ...editForm, username: e.target.value })} required />
            </div>
            <div className="field">
              <label>New Password (optional)</label>
              <input type="password" placeholder="Leave empty to keep current" value={editForm.password} onChange={(e) => setEditForm({ ...editForm, password: e.target.value })} />
            </div>
            <div className="field">
              <label>SSL Mode</label>
              <select value={editForm.sslmode} onChange={(e) => setEditForm({ ...editForm, sslmode: e.target.value })}>
                <option value="disable">disable</option>
                <option value="prefer">prefer</option>
                <option value="require">require</option>
              </select>
            </div>
            <div className="field toggle-field">
              <label>Query Insights Source</label>
              <label className="toggle-check">
                <input
                  type="checkbox"
                  checked={!!editForm.use_pg_stat_statements}
                  onChange={(e) => setEditForm({ ...editForm, use_pg_stat_statements: e.target.checked })}
                />
                <span className="toggle-ui" aria-hidden="true" />
                <span className="toggle-copy">
                  <strong>Use pg_stat_statements for this target</strong>
                  <small>Disable this if the extension is unavailable on the target.</small>
                </span>
              </label>
            </div>
            <div className="field field-full">
              <label>Responsible Users (Target Owners)</label>
              <OwnerPicker
                candidates={ownerCandidates}
                selectedIds={editForm.owner_user_ids}
                query={editOwnerQuery}
                onQueryChange={setEditOwnerQuery}
                onToggle={(userId) => setEditForm({ ...editForm, owner_user_ids: toggleOwner(editForm.owner_user_ids, userId) })}
              />
              <small>Only selected users will receive email notifications for this target's alerts.</small>
            </div>
            <div className="field submit-field field-full">
              <div className="form-actions">
                <button type="button" className="secondary-btn" onClick={cancelEdit}>Cancel</button>
                <button className="primary-btn" disabled={saveState.loading}>{saveState.loading ? "Saving..." : "Save changes"}</button>
              </div>
            </div>
          </form>
          {saveState.message && <div className="test-connection-result">{saveState.message}</div>}
        </section>
      )}

      {canManage && (
        <details className="card collapsible tips">
          <summary className="collapse-head">
            <div>
              <h3>Troubleshooting</h3>
              <p>Quick checks for the most common connection issues.</p>
            </div>
            <span className="collapse-chevron" aria-hidden="true">v</span>
          </summary>
          <p>
            <code>Connection refused</code>: host/port is wrong or database is unreachable.
          </p>
          <p>
            <code>rejected SSL upgrade</code>: set SSL mode to <code>disable</code>.
          </p>
          <p>
            <code>localhost</code> points to the backend container itself, not your host machine.
          </p>
        </details>
      )}

      <div className="card targets-table">
        {loading ? (
          <p>Loading targets...</p>
        ) : (
          <table>
            <thead>
              <tr>
                <th>Name</th>
                <th>Host</th>
                <th>DB</th>
                <th>Owners</th>
                <th>Query Insights</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {targets.map((t) => (
                <tr key={t.id}>
                  <td>{t.name}</td>
                  <td>{t.host}:{t.port}</td>
                  <td>{t.dbname}</td>
                  <td>{Array.isArray(t.owner_user_ids) ? t.owner_user_ids.length : 0}</td>
                  <td>
                    <span className={`status-chip ${t.use_pg_stat_statements ? "ok" : "warning"}`}>
                      {t.use_pg_stat_statements ? "Enabled" : "Disabled"}
                    </span>
                  </td>
                  <td>
                    <div className="row-actions">
                      <Link className="table-action-btn details" to={`/targets/${t.id}`}>
                        <span aria-hidden="true">
                          <svg viewBox="0 0 24 24" width="13" height="13">
                            <path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" fill="currentColor" />
                          </svg>
                        </span>
                        Details
                      </Link>
                      {canManage && (
                        <button className="table-action-btn edit" onClick={() => startEdit(t)}>
                          <span aria-hidden="true">
                            <svg viewBox="0 0 24 24" width="13" height="13">
                              <path d="M3 17.25V21h3.75L19.81 7.94l-3.75-3.75L3 17.25zm2.92 2.33H5v-.92l10.06-10.06.92.92L5.92 19.58zM20.71 6.04a1 1 0 0 0 0-1.41L19.37 3.3a1 1 0 0 0-1.41 0l-1.13 1.12 3.75 3.75 1.13-1.13z" fill="currentColor" />
                            </svg>
                          </span>
                          Edit
                        </button>
                      )}
                      {canManage && (
                        <button className="table-action-btn delete" onClick={() => deleteTarget(t.id)}>
                          <span aria-hidden="true">
                            <svg viewBox="0 0 24 24" width="13" height="13">
                              <path d="M6 7h12l-1 13H7L6 7zm3-3h6l1 2H8l1-2z" fill="currentColor" />
                            </svg>
                          </span>
                          Delete
                        </button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}
