import { useState, useEffect, useCallback } from "react";
import { useSearchParams } from "react-router-dom";
import api from "../api/client";
import useMqttWebSocket from "./useMqttWebSocket";

const LEVEL_STYLES = {
  INFO: { bg: "var(--badge-blue-bg)", color: "var(--badge-blue-text)" },
  WARN: { bg: "#3d2e00", color: "#fbbf24" },
  ERROR: { bg: "var(--danger-bg)", color: "var(--danger-text)" },
};

export default function LogViewer() {
  const [searchParams] = useSearchParams();
  const [devices, setDevices] = useState([]);
  const [selectedDevice, setSelectedDevice] = useState(searchParams.get("device") || "");
  const [logs, setLogs] = useState([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [levelFilter, setLevelFilter] = useState("");
  const [searchText, setSearchText] = useState("");
  const [autoRefresh, setAutoRefresh] = useState(false);
  const [liveLogs, setLiveLogs] = useState([]);
  const [offset, setOffset] = useState(0);
  const limit = 100;

  useEffect(() => {
    api.get("/devices").then((data) => {
      setDevices(data.devices || []);
      if (!selectedDevice && data.devices?.length > 0) {
        setSelectedDevice(data.devices[0].device_id || "");
      }
    }).catch(() => {});
  }, []);

  const fetchLogs = async () => {
    if (!selectedDevice) return;
    setLoading(true);
    try {
      const params = new URLSearchParams();
      if (levelFilter) params.set("level", levelFilter);
      if (searchText) params.set("search", searchText);
      params.set("limit", limit.toString());
      params.set("offset", offset.toString());
      const data = await api.get(`/mqtt/logs/${selectedDevice}?${params}`);
      setLogs(data.logs || []);
      setTotal(data.total || 0);
      setError("");
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (selectedDevice) {
      setOffset(0);
      fetchLogs();
    }
  }, [selectedDevice, levelFilter, searchText]);

  useEffect(() => {
    if (selectedDevice && offset > 0) fetchLogs();
  }, [offset]);

  useEffect(() => {
    if (!autoRefresh || !selectedDevice) return;
    const interval = setInterval(fetchLogs, 5000);
    return () => clearInterval(interval);
  }, [autoRefresh, selectedDevice, levelFilter, searchText]);

  const handleWsMessage = useCallback(
    (data) => {
      if (
        data.type === "logs" &&
        (!selectedDevice || data.device_serial === selectedDevice)
      ) {
        const logEntry = {
          id: Date.now(),
          device_serial: data.device_serial,
          level: data.payload?.level?.includes("EROR")
            ? "ERROR"
            : data.payload?.level?.includes("WARN")
            ? "WARN"
            : "INFO",
          message: data.payload?.message || "",
          device_timestamp: data.payload?.timestamp,
          received_at: new Date().toISOString(),
          _live: true,
        };
        setLiveLogs((prev) => [logEntry, ...prev].slice(0, 50));
      }
    },
    [selectedDevice]
  );

  useMqttWebSocket({ enabled: true, onMessage: handleWsMessage });

  const allLogs = [...liveLogs.filter((l) => {
    if (levelFilter && l.level !== levelFilter) return false;
    if (searchText && !l.message.toLowerCase().includes(searchText.toLowerCase())) return false;
    return true;
  }), ...logs];

  const hasMore = offset + limit < total;

  return (
    <div>
      <h1 className="text-2xl font-bold mb-6" style={{ color: "var(--text-heading)" }}>
        Log Viewer
      </h1>

      {/* Filters */}
      <div className="mb-4 space-y-3">
        <div className="flex flex-wrap gap-3 items-end">
          <div>
            <label className="block text-xs mb-1" style={{ color: "var(--text-muted)" }}>Device</label>
            <select
              value={selectedDevice}
              onChange={(e) => { setSelectedDevice(e.target.value); setLiveLogs([]); }}
              className="px-3 py-2 rounded-md text-sm border"
              style={{ backgroundColor: "var(--bg-card)", color: "var(--text-primary)", borderColor: "var(--border-primary)" }}
            >
              <option value="">Select device...</option>
              {devices.map((d) => (
                <option key={d.id} value={d.device_id}>
                  {d.device_name || d.device_id} ({d.device_id})
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-xs mb-1" style={{ color: "var(--text-muted)" }}>Level</label>
            <select
              value={levelFilter}
              onChange={(e) => setLevelFilter(e.target.value)}
              className="px-3 py-2 rounded-md text-sm border"
              style={{ backgroundColor: "var(--bg-card)", color: "var(--text-primary)", borderColor: "var(--border-primary)" }}
            >
              <option value="">All Levels</option>
              <option value="INFO">INFO</option>
              <option value="WARN">WARN</option>
              <option value="ERROR">ERROR</option>
            </select>
          </div>
          <div className="flex-1 min-w-48">
            <label className="block text-xs mb-1" style={{ color: "var(--text-muted)" }}>Search</label>
            <input
              type="text"
              value={searchText}
              onChange={(e) => setSearchText(e.target.value)}
              placeholder="Search log messages..."
              className="w-full px-3 py-2 rounded-md text-sm border"
            />
          </div>
          <div className="flex items-center gap-3">
            <label className="flex items-center gap-2 text-sm cursor-pointer" style={{ color: "var(--text-secondary)" }}>
              <input
                type="checkbox"
                checked={autoRefresh}
                onChange={(e) => setAutoRefresh(e.target.checked)}
              />
              Auto-refresh
            </label>
            <button
              onClick={fetchLogs}
              className="px-3 py-2 text-sm rounded-md border hover:opacity-80 cursor-pointer"
              style={{ borderColor: "var(--border-primary)", color: "var(--text-primary)" }}
            >
              Refresh
            </button>
          </div>
        </div>
        <div className="text-sm" style={{ color: "var(--text-muted)" }}>
          {total} total logs{liveLogs.length > 0 ? ` + ${liveLogs.length} live` : ""}
        </div>
      </div>

      {error && (
        <div
          className="text-sm rounded-md p-3 mb-4 border"
          style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}
        >
          {error}
        </div>
      )}

      {!selectedDevice ? (
        <div
          className="rounded-lg p-8 text-center text-sm border"
          style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)", color: "var(--text-muted)" }}
        >
          Select a device to view logs.
        </div>
      ) : loading && logs.length === 0 ? (
        <div className="text-center py-8" style={{ color: "var(--text-muted)" }}>Loading...</div>
      ) : allLogs.length === 0 ? (
        <div
          className="rounded-lg p-8 text-center text-sm border"
          style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)", color: "var(--text-muted)" }}
        >
          No logs found for this device.
        </div>
      ) : (
        <>
          <div
            className="rounded-lg overflow-hidden border"
            style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
          >
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr style={{ backgroundColor: "var(--bg-primary)", borderBottom: "1px solid var(--border-primary)" }}>
                    <th className="px-4 py-3 text-left font-medium w-44" style={{ color: "var(--text-secondary)" }}>Time</th>
                    <th className="px-4 py-3 text-left font-medium w-20" style={{ color: "var(--text-secondary)" }}>Level</th>
                    <th className="px-4 py-3 text-left font-medium" style={{ color: "var(--text-secondary)" }}>Message</th>
                  </tr>
                </thead>
                <tbody>
                  {allLogs.map((log, index) => {
                    const style = LEVEL_STYLES[log.level] || LEVEL_STYLES.INFO;
                    return (
                      <tr
                        key={log._live ? `live-${log.id}` : log.id}
                        style={{
                          borderBottom: index < allLogs.length - 1 ? "1px solid var(--border-primary)" : "none",
                          backgroundColor: log._live ? "rgba(116, 184, 22, 0.05)" : "transparent",
                        }}
                      >
                        <td className="px-4 py-2.5 text-xs font-mono" style={{ color: "var(--text-muted)" }}>
                          {log.received_at?.replace("T", " ").substring(0, 19)}
                          {log._live && (
                            <span className="ml-1 text-xs" style={{ color: "var(--accent)" }}>LIVE</span>
                          )}
                        </td>
                        <td className="px-4 py-2.5">
                          <span
                            className="px-2 py-0.5 text-xs rounded-full"
                            style={{ backgroundColor: style.bg, color: style.color }}
                          >
                            {log.level}
                          </span>
                        </td>
                        <td className="px-4 py-2.5 font-mono text-xs" style={{ color: "var(--text-primary)" }}>
                          {log.message}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>

          {/* Pagination */}
          <div className="flex items-center justify-between mt-4">
            <button
              onClick={() => setOffset(Math.max(0, offset - limit))}
              disabled={offset === 0}
              className="px-3 py-1.5 text-sm rounded-md border hover:opacity-80 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
              style={{ borderColor: "var(--border-primary)", color: "var(--text-primary)" }}
            >
              Previous
            </button>
            <span className="text-sm" style={{ color: "var(--text-muted)" }}>
              Showing {offset + 1}–{Math.min(offset + limit, total)} of {total}
            </span>
            <button
              onClick={() => setOffset(offset + limit)}
              disabled={!hasMore}
              className="px-3 py-1.5 text-sm rounded-md border hover:opacity-80 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
              style={{ borderColor: "var(--border-primary)", color: "var(--text-primary)" }}
            >
              Next
            </button>
          </div>
        </>
      )}
    </div>
  );
}
