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

function getTargetGroupMeta(target) {
  const tags = target?.tags || {};
  if (tags.monitor_mode !== "all_databases" || !tags.monitor_group_id) return null;
  return {
    id: tags.monitor_group_id,
    name: tags.monitor_group_name || target.name || "All databases",
  };
}

export function DashboardPage() {
  const { tokens, refresh, alertStatus } = useAuth();
  const [targets, setTargets] = useState([]);
  const [search, setSearch] = useState("");
  const [openGroups, setOpenGroups] = useState({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        const targetRows = await apiFetch("/targets", {}, tokens, refresh);
        if (active) {
          setTargets(targetRows);
        }
      } catch (e) {
        if (active) setError(String(e.message || e));
      } finally {
        if (active) setLoading(false);
      }
    })();
    return () => {
      active = false;
    };
  }, [tokens, refresh]);

  if (loading) return <div className="card">Loading dashboard...</div>;
  if (error) return <div className="card error">{error}</div>;

  const targetSeverities = new Map();
  for (const item of alertStatus.warnings || []) {
    if (!targetSeverities.has(item.target_id)) targetSeverities.set(item.target_id, "warning");
  }
  for (const item of alertStatus.alerts || []) {
    targetSeverities.set(item.target_id, "alert");
  }

  const affectedTargetCount = targetSeverities.size;
  const okCount = Math.max(0, targets.length - affectedTargetCount);
  const filteredTargets = targets.filter((t) => {
    const q = search.trim().toLowerCase();
    if (!q) return true;
    return (
      (t.name || "").toLowerCase().includes(q) ||
      (t.host || "").toLowerCase().includes(q) ||
      (t.dbname || "").toLowerCase().includes(q)
    );
  });
  const groupedRows = [];
  const groupedMap = new Map();
  for (const t of filteredTargets) {
    const meta = getTargetGroupMeta(t);
    if (!meta) {
      groupedRows.push({ type: "single", target: t });
      continue;
    }
    if (!groupedMap.has(meta.id)) {
      const groupRow = { type: "group", groupId: meta.id, groupName: meta.name, targets: [] };
      groupedMap.set(meta.id, groupRow);
      groupedRows.push(groupRow);
    }
    groupedMap.get(meta.id).targets.push(t);
  }

  return (
    <div className="dashboard-page">
      <h2>Dashboard Overview</h2>
      <p className="dashboard-subtitle">Real-time snapshot of monitored PostgreSQL targets.</p>
      <div className="dashboard-kpis-grid">
        <div className="card stat kpi-card">
          <div className="kpi-orb blue" />
          <strong>{targets.length}</strong>
          <span className="kpi-label">Total Targets</span>
        </div>
        <div className="card stat kpi-card ok">
          <div className="kpi-orb green" />
          <strong>{okCount}</strong>
          <span className="kpi-label">Status OK</span>
        </div>
        <div className="card stat kpi-card warning">
          <div className="kpi-orb amber" />
          <strong>{alertStatus.warning_count || 0}</strong>
          <span className="kpi-label">Warnings</span>
        </div>
        <div className="card stat kpi-card alert">
          <div className="kpi-orb red" />
          <strong>{alertStatus.alert_count || 0}</strong>
          <span className="kpi-label">Alerts</span>
        </div>
      </div>

      <div className="card dashboard-targets-card">
        <div className="dashboard-targets-head">
          <div>
            <h3>Targets</h3>
            <span>{filteredTargets.length} shown of {targets.length} registered</span>
          </div>
          <div className="dashboard-target-search">
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search by name, host, or database..."
            />
          </div>
        </div>

        <div className="dashboard-target-list">
          {groupedRows.map((row) => {
            if (row.type === "single") {
              const t = row.target;
              const severity = targetSeverities.get(t.id) || "ok";
              return (
                <article className="dashboard-target-card" key={`single-${t.id}`}>
                  <div className="target-main">
                    <div className="target-title-row">
                      <h4>{t.name}</h4>
                      <span className={`status-chip ${severity}`}>
                        {severity === "alert" ? "Alert" : severity === "warning" ? "Warning" : "OK"}
                      </span>
                    </div>
                    <p><strong>Host:</strong> {t.host}:{t.port}</p>
                    <p><strong>DB:</strong> {t.dbname}</p>
                  </div>
                  <div className="target-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>
                  </div>
                </article>
              );
            }

            const highestSeverity = row.targets.some((t) => targetSeverities.get(t.id) === "alert")
              ? "alert"
              : row.targets.some((t) => targetSeverities.get(t.id) === "warning")
                ? "warning"
                : "ok";
            const first = row.targets[0];
            const isOpen = !!openGroups[row.groupId];
            return (
              <article className="dashboard-target-card dashboard-target-group" key={`group-${row.groupId}`}>
                <div className="target-main">
                  <div className="target-title-row">
                    <h4>{row.groupName}</h4>
                    <span className={`status-chip ${highestSeverity}`}>
                      {highestSeverity === "alert" ? "Alert" : highestSeverity === "warning" ? "Warning" : "OK"}
                    </span>
                  </div>
                  <p><strong>Host:</strong> {first.host}:{first.port}</p>
                  <p><strong>DB:</strong> All databases ({row.targets.length})</p>
                </div>
                <div className="target-actions">
                  <button
                    type="button"
                    className="table-action-btn edit"
                    onClick={() => setOpenGroups((prev) => ({ ...prev, [row.groupId]: !prev[row.groupId] }))}
                  >
                    {isOpen ? "Hide DBs" : "Show DBs"}
                  </button>
                </div>
                {isOpen && (
                  <div className="dashboard-group-list">
                    {row.targets.map((t) => {
                      const severity = targetSeverities.get(t.id) || "ok";
                      return (
                        <div key={`child-${t.id}`} className="dashboard-group-item">
                          <div>
                            <strong>{t.dbname}</strong>
                            <span className={`status-chip ${severity}`}>
                              {severity === "alert" ? "Alert" : severity === "warning" ? "Warning" : "OK"}
                            </span>
                          </div>
                          <Link className="table-action-btn details small-btn" to={`/targets/${t.id}`}>
                            Details
                          </Link>
                        </div>
                      );
                    })}
                  </div>
                )}
              </article>
            );
          })}
          {filteredTargets.length === 0 && (
            <div className="dashboard-empty">No targets match your search.</div>
          )}
        </div>
      </div>
    </div>
  );
}
