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

const initialForm = {
  name: "",
  description: "",
  target_id: "",
  sql_text: "SELECT count(*)::float FROM pg_stat_activity WHERE state = 'active'",
  comparison: "gte",
  warning_threshold: "",
  alert_threshold: "",
  enabled: true,
};

function formatAlertValue(value) {
  if (value === null || value === undefined) return "-";
  if (Number.isInteger(value)) return String(value);
  return Number(value).toFixed(2);
}

function formatTs(ts) {
  if (!ts) return "-";
  return new Date(ts).toLocaleString();
}

function buildAlertSuggestions(item) {
  const name = (item?.name || "").toLowerCase();
  const category = (item?.category || "").toLowerCase();
  const source = (item?.source || "").toLowerCase();
  const value = Number(item?.value || 0);
  const suggestions = [];

  if (name.includes("reachability") || name.includes("connectivity") || category === "availability") {
    suggestions.push("Verify host, port, firewall rules, and network routing between backend container and DB target.");
    suggestions.push("Check PostgreSQL `listen_addresses` and `pg_hba.conf` on the monitored instance.");
  }
  if (name.includes("freshness") || item?.message?.toLowerCase().includes("no metrics")) {
    suggestions.push("Check collector logs and polling interval. Confirm the target credentials are still valid.");
    suggestions.push("Run a manual connection test in Targets Management and verify SSL mode.");
  }
  if (name.includes("cache hit") || category === "performance") {
    suggestions.push("Inspect slow queries and add/adjust indexes for frequent WHERE/JOIN columns.");
    suggestions.push("Review shared buffers and query patterns that cause high disk reads.");
  }
  if (name.includes("lock") || category === "contention") {
    suggestions.push("Inspect blocking sessions in `pg_stat_activity` and long transactions.");
    suggestions.push("Reduce transaction scope/duration and add missing indexes to avoid lock escalation.");
  }
  if (name.includes("deadlock")) {
    suggestions.push("Enforce a consistent table access order in transactions to prevent deadlocks.");
    suggestions.push("Retry deadlocked transactions in the application with backoff.");
  }
  if (name.includes("checkpoint") || category === "io") {
    suggestions.push("Review `max_wal_size`, `checkpoint_timeout`, and write burst patterns.");
    suggestions.push("Check disk throughput and WAL pressure during peak load.");
  }
  if (name.includes("rollback")) {
    suggestions.push("Investigate application errors causing transaction rollbacks.");
    suggestions.push("Validate constraints/input earlier to reduce failed writes.");
  }
  if (name.includes("query") || category === "query" || source === "custom") {
    suggestions.push("Run `EXPLAIN (ANALYZE, BUFFERS)` for the affected query and optimize highest-cost nodes.");
    suggestions.push("Prioritize fixes for high total-time queries first, then high mean-time queries.");
  }
  if (value > 0 && item?.comparison && item?.alert_threshold !== null && item?.alert_threshold !== undefined) {
    suggestions.push(`Current value is ${value.toFixed(2)} with threshold rule ${item.comparison} ${Number(item.alert_threshold).toFixed(2)}.`);
  }
  if (!suggestions.length) {
    suggestions.push("Start with target activity, locks, and query insights to isolate the root cause.");
    suggestions.push("Compare current values to the last stable period and tune threshold sensitivity if needed.");
  }

  return suggestions.slice(0, 4);
}

export function AlertsPage() {
  const location = useLocation();
  const { tokens, refresh, me, alertStatus } = useAuth();
  const [targets, setTargets] = useState([]);
  const [definitions, setDefinitions] = useState([]);
  const [form, setForm] = useState(initialForm);
  const [expandedKey, setExpandedKey] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);
  const [standardReference, setStandardReference] = useState([]);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState("");
  const [saving, setSaving] = useState(false);

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

  const loadAll = async () => {
    try {
      setError("");
      const [targetRows, referenceRows] = await Promise.all([
        apiFetch("/targets", {}, tokens, refresh),
        apiFetch("/alerts/standard-reference", {}, tokens, refresh),
      ]);
      setTargets(targetRows);
      setStandardReference(Array.isArray(referenceRows) ? referenceRows : []);

      if (canManageAlerts) {
        const defs = await apiFetch("/alerts/definitions", {}, tokens, refresh);
        setDefinitions(defs);
      }
    } catch (e) {
      setError(String(e.message || e));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadAll();
  }, [canManageAlerts]);

  const targetOptions = useMemo(
    () => [{ id: "", name: "All targets" }, ...targets.map((t) => ({ id: String(t.id), name: `${t.name} (${t.host}:${t.port})` }))],
    [targets]
  );

  const createDefinition = async (e) => {
    e.preventDefault();
    setSaving(true);
    setTestResult("");
    try {
      await apiFetch(
        "/alerts/definitions",
        {
          method: "POST",
          body: JSON.stringify({
            name: form.name,
            description: form.description || null,
            target_id: form.target_id ? Number(form.target_id) : null,
            sql_text: form.sql_text,
            comparison: form.comparison,
            warning_threshold: form.warning_threshold === "" ? null : Number(form.warning_threshold),
            alert_threshold: Number(form.alert_threshold),
            enabled: !!form.enabled,
          }),
        },
        tokens,
        refresh
      );
      setForm(initialForm);
      await loadAll();
    } catch (e) {
      setError(String(e.message || e));
    } finally {
      setSaving(false);
    }
  };

  const testDefinition = async () => {
    if (!form.target_id) {
      setTestResult("Select a specific target to test this SQL query.");
      return;
    }
    setTesting(true);
    setTestResult("");
    try {
      const res = await apiFetch(
        "/alerts/definitions/test",
        {
          method: "POST",
          body: JSON.stringify({
            target_id: Number(form.target_id),
            sql_text: form.sql_text,
          }),
        },
        tokens,
        refresh
      );
      if (res.ok) {
        setTestResult(`Query test succeeded. Returned value: ${formatAlertValue(res.value)}`);
      } else {
        setTestResult(`Query test failed: ${res.error}`);
      }
    } catch (e) {
      setTestResult(String(e.message || e));
    } finally {
      setTesting(false);
    }
  };

  const removeDefinition = async (definitionId) => {
    if (!confirm("Delete this custom alert definition?")) return;
    try {
      await apiFetch(`/alerts/definitions/${definitionId}`, { method: "DELETE" }, tokens, refresh);
      await loadAll();
    } catch (e) {
      setError(String(e.message || e));
    }
  };

  const toggleDefinition = async (definition) => {
    try {
      await apiFetch(
        `/alerts/definitions/${definition.id}`,
        { method: "PUT", body: JSON.stringify({ enabled: !definition.enabled }) },
        tokens,
        refresh
      );
      await loadAll();
    } catch (e) {
      setError(String(e.message || e));
    }
  };

  const toggleExpanded = (key) => {
    setExpandedKey((prev) => (prev === key ? "" : key));
  };

  useEffect(() => {
    const params = new URLSearchParams(location.search);
    const openKey = params.get("open");
    if (!openKey) return;
    setExpandedKey(openKey);
    const id = `alert-item-${openKey.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
    setTimeout(() => {
      const el = document.getElementById(id);
      if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
    }, 120);
  }, [location.search]);

  if (loading) return <div className="card">Loading alerts...</div>;

  return (
    <div className="alerts-page">
      <h2>Alerts</h2>
      <p className="alerts-subtitle">Warnings are early signals. Alerts are critical thresholds reached or exceeded.</p>
      {error && <div className="card error">{error}</div>}

      <div className="grid two alerts-kpis">
        <div className="card alerts-kpi warning">
          <strong>{alertStatus.warning_count || 0}</strong>
          <span>Warnings</span>
        </div>
        <div className="card alerts-kpi alert">
          <strong>{alertStatus.alert_count || 0}</strong>
          <span>Alerts</span>
        </div>
      </div>

      <div className="grid two">
        <section className="card">
          <h3>Warnings</h3>
          {alertStatus.warnings?.length ? (
            <div className="alerts-list">
              {alertStatus.warnings.map((item) => {
                const isOpen = expandedKey === item.alert_key;
                const suggestions = buildAlertSuggestions(item);
                return (
                  <article
                    className={`alert-item warning ${isOpen ? "is-open" : ""}`}
                    key={item.alert_key}
                    id={`alert-item-${item.alert_key.replace(/[^a-zA-Z0-9_-]/g, "-")}`}
                    onClick={() => toggleExpanded(item.alert_key)}
                    role="button"
                    tabIndex={0}
                  >
                    <div className="alert-item-head">
                      <span className="alert-badge warning">Warning</span>
                      <strong>{item.name}</strong>
                      <small>{item.target_name}</small>
                    </div>
                    <p>{item.description}</p>
                    <p className="alert-message">{item.message}</p>
                    {isOpen && (
                      <div className="alert-details-grid">
                        <div><span>Source</span><strong>{item.source}</strong></div>
                        <div><span>Category</span><strong>{item.category}</strong></div>
                        <div><span>Current Value</span><strong>{formatAlertValue(item.value)}</strong></div>
                        <div><span>Comparison</span><strong>{item.comparison}</strong></div>
                        <div><span>Warning Threshold</span><strong>{formatAlertValue(item.warning_threshold)}</strong></div>
                        <div><span>Alert Threshold</span><strong>{formatAlertValue(item.alert_threshold)}</strong></div>
                        <div><span>Checked At</span><strong>{formatTs(item.checked_at)}</strong></div>
                        <div><span>Target ID</span><strong>{item.target_id}</strong></div>
                        {item.sql_text && <div className="alert-sql"><code>{item.sql_text}</code></div>}
                        <div className="alert-suggestions">
                          <h4>Recommended actions</h4>
                          <ul>
                            {suggestions.map((tip, idx) => <li key={idx}>{tip}</li>)}
                          </ul>
                        </div>
                      </div>
                    )}
                  </article>
                );
              })}
            </div>
          ) : (
            <p className="muted">No warning-level alerts right now.</p>
          )}
        </section>

        <section className="card">
          <h3>Alerts</h3>
          {alertStatus.alerts?.length ? (
            <div className="alerts-list">
              {alertStatus.alerts.map((item) => {
                const isOpen = expandedKey === item.alert_key;
                const suggestions = buildAlertSuggestions(item);
                return (
                  <article
                    className={`alert-item alert ${isOpen ? "is-open" : ""}`}
                    key={item.alert_key}
                    id={`alert-item-${item.alert_key.replace(/[^a-zA-Z0-9_-]/g, "-")}`}
                    onClick={() => toggleExpanded(item.alert_key)}
                    role="button"
                    tabIndex={0}
                  >
                    <div className="alert-item-head">
                      <span className="alert-badge alert">Alert</span>
                      <strong>{item.name}</strong>
                      <small>{item.target_name}</small>
                    </div>
                    <p>{item.description}</p>
                    <p className="alert-message">{item.message}</p>
                    {isOpen && (
                      <div className="alert-details-grid">
                        <div><span>Source</span><strong>{item.source}</strong></div>
                        <div><span>Category</span><strong>{item.category}</strong></div>
                        <div><span>Current Value</span><strong>{formatAlertValue(item.value)}</strong></div>
                        <div><span>Comparison</span><strong>{item.comparison}</strong></div>
                        <div><span>Warning Threshold</span><strong>{formatAlertValue(item.warning_threshold)}</strong></div>
                        <div><span>Alert Threshold</span><strong>{formatAlertValue(item.alert_threshold)}</strong></div>
                        <div><span>Checked At</span><strong>{formatTs(item.checked_at)}</strong></div>
                        <div><span>Target ID</span><strong>{item.target_id}</strong></div>
                        {item.sql_text && <div className="alert-sql"><code>{item.sql_text}</code></div>}
                        <div className="alert-suggestions">
                          <h4>Recommended actions</h4>
                          <ul>
                            {suggestions.map((tip, idx) => <li key={idx}>{tip}</li>)}
                          </ul>
                        </div>
                      </div>
                    )}
                  </article>
                );
              })}
            </div>
          ) : (
            <p className="muted">No critical alerts right now.</p>
          )}
        </section>
      </div>

      <details className="card collapsible">
        <summary className="collapse-head">
          <div>
            <h3>Standard Alert Reference</h3>
            <p>What each built-in alert checks and which default thresholds are used.</p>
          </div>
          <span className="collapse-chevron" aria-hidden="true">v</span>
        </summary>
        <div className="standard-alerts-note">
          Some rules include traffic guards to reduce noise (for example rollback ratio needs enough transactions).
        </div>
        <div className="standard-alerts-table-wrap">
          <table className="standard-alerts-table">
            <thead>
              <tr>
                <th>Alert</th>
                <th>Checks</th>
                <th>Comparison</th>
                <th>Warning</th>
                <th>Alert</th>
              </tr>
            </thead>
            <tbody>
              {standardReference.length > 0 ? (
                standardReference.map((row) => (
                  <tr key={row.key || row.name}>
                    <td>{row.name}</td>
                    <td>{row.checks}</td>
                    <td><code>{row.comparison}</code></td>
                    <td>{row.warning}</td>
                    <td>{row.alert}</td>
                  </tr>
                ))
              ) : (
                <tr>
                  <td colSpan={5} className="muted">No standard alert metadata available.</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </details>

      {canManageAlerts && (
        <>
          <details className="card collapsible">
            <summary className="collapse-head">
              <div>
                <h3>Create Custom Alert</h3>
                <p>Admins and operators can add SQL-based checks with warning and alert thresholds.</p>
              </div>
              <span className="collapse-chevron" aria-hidden="true">v</span>
            </summary>
            <form className="alert-form grid two" onSubmit={createDefinition}>
              <div className="field">
                <label>Name</label>
                <input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="e.g. High Active Sessions" required />
              </div>
              <div className="field">
                <label>Target Scope</label>
                <select value={form.target_id} onChange={(e) => setForm({ ...form, target_id: e.target.value })}>
                  {targetOptions.map((opt) => (
                    <option key={opt.id || "all"} value={opt.id}>
                      {opt.name}
                    </option>
                  ))}
                </select>
              </div>
              <div className="field">
                <label>Comparison</label>
                <select value={form.comparison} onChange={(e) => setForm({ ...form, comparison: e.target.value })}>
                  <option value="gte">greater than or equal (&gt;=)</option>
                  <option value="gt">greater than (&gt;)</option>
                  <option value="lte">less than or equal (&lt;=)</option>
                  <option value="lt">less than (&lt;)</option>
                </select>
              </div>
              <div className="field">
                <label>Description</label>
                <input value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} placeholder="What does this check validate?" />
              </div>
              <div className="field">
                <label>Warning Threshold (optional)</label>
                <input type="number" step="any" value={form.warning_threshold} onChange={(e) => setForm({ ...form, warning_threshold: e.target.value })} placeholder="e.g. 20" />
              </div>
              <div className="field">
                <label>Alert Threshold</label>
                <input type="number" step="any" value={form.alert_threshold} onChange={(e) => setForm({ ...form, alert_threshold: e.target.value })} placeholder="e.g. 50" required />
              </div>
              <div className="field field-full">
                <label>SQL Query (must return one numeric value)</label>
                <textarea
                  rows={4}
                  value={form.sql_text}
                  onChange={(e) => setForm({ ...form, sql_text: e.target.value })}
                  placeholder="SELECT count(*)::float FROM pg_stat_activity WHERE state = 'active'"
                  required
                />
              </div>
              <div className="alert-form-actions field-full">
                <button type="button" className="secondary-btn" onClick={testDefinition} disabled={testing}>
                  {testing ? "Testing..." : "Test query output"}
                </button>
                <button className="primary-btn" disabled={saving}>
                  {saving ? "Creating..." : "Create custom alert"}
                </button>
              </div>
              {testResult && <div className="test-connection-result">{testResult}</div>}
            </form>
          </details>

          <details className="card collapsible">
            <summary className="collapse-head">
              <div>
                <h3>Custom Alert Definitions</h3>
                <p>All saved SQL-based alert rules.</p>
              </div>
              <span className="collapse-chevron" aria-hidden="true">v</span>
            </summary>
            {definitions.length ? (
              <table>
                <thead>
                  <tr>
                    <th>Name</th>
                    <th>Scope</th>
                    <th>Comparison</th>
                    <th>Warn</th>
                    <th>Alert</th>
                    <th>Status</th>
                    <th>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {definitions.map((d) => (
                    <tr key={d.id}>
                      <td>{d.name}</td>
                      <td>{d.target_id ? targets.find((t) => t.id === d.target_id)?.name || `Target #${d.target_id}` : "All targets"}</td>
                      <td>{d.comparison}</td>
                      <td>{d.warning_threshold ?? "-"}</td>
                      <td>{d.alert_threshold}</td>
                      <td>{d.enabled ? "Enabled" : "Disabled"}</td>
                      <td>
                        <div className="row-actions">
                          <button type="button" className={`table-action-btn toggle ${d.enabled ? "enabled" : "disabled"}`} onClick={() => toggleDefinition(d)}>
                            <span aria-hidden="true">
                              <svg viewBox="0 0 24 24" width="13" height="13">
                                <path d="M7 12h10M12 7v10" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" />
                              </svg>
                            </span>
                            {d.enabled ? "Disable" : "Enable"}
                          </button>
                          <button type="button" className="table-action-btn delete" onClick={() => removeDefinition(d.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>
            ) : (
              <p className="muted">No custom alerts created yet.</p>
            )}
          </details>
        </>
      )}
    </div>
  );
}
