import React, { useState, useMemo, useEffect, useCallback } from "react";
import { useParams, useNavigate } from "react-router-dom";
import axiosInstance from "../../../utils/axiosConfig";
import { ACTIVITY_LOG_URL, FORMS_LOGS_URL, AUDIT_LOGS_JOINED_URL } from "../../../utils/config";
import ActivityLogHeader from "./pages/ActivityLogHeader";
import ActivityLogControls from "./pages/ActivityLogControls";
import ActivityLogTable from "./pages/ActivityLogTable";
import ActivityLogCards from "./pages/ActivityLogCards";
import Pagination from "../../common/Pagination";
import "./styles/ActivityLog.css";

const POLL_INTERVAL_MS = 30000; // 30 seconds for real-time updates

const SECTION_FROM_PARAM = {
  "user-logs": "user",
  "forms-logs": "forms",
  "audit-logs": "audit",
};
const SECTION_LABELS = {
  user: "User Logs",
  forms: "Form Logs",
  audit: "Audit Logs",
};

const ActivityLog = () => {
  const { section: sectionParam } = useParams();
  const navigate = useNavigate();
  const activeSection = SECTION_FROM_PARAM[sectionParam] ?? "user";

  useEffect(() => {
    if (sectionParam && !SECTION_FROM_PARAM[sectionParam]) {
      navigate("/activity-log/user-logs", { replace: true });
    }
  }, [sectionParam, navigate]);

  const [activities, setActivities] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [entriesPerPage, setEntriesPerPage] = useState(10);
  const [searchText, setSearchText] = useState("");
  const [viewMode, setViewMode] = useState("list"); // "list" | "card"

  const formatTimestamp = (ts) => {
    if (!ts) return "—";
    const d = new Date(ts);
    const y = d.getFullYear();
    const m = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    const h = String(d.getHours()).padStart(2, "0");
    const min = String(d.getMinutes()).padStart(2, "0");
    const s = String(d.getSeconds()).padStart(2, "0");
    return `${y}-${m}-${day} ${h}:${min}:${s}`;
  };

  const fetchActivities = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      if (activeSection === "forms") {
        const res = await axiosInstance.get(FORMS_LOGS_URL, {
          params: { limit: 1000 },
        });
        const data = res.data?.data;
        const rows = Array.isArray(data) ? data : [];
        const list = rows.map((r) => ({
          timestamp: formatTimestamp(r.created_at),
          user: r.user_name ?? "—",
          action: r.action ?? r.form_type ?? "Form",
          type: "form",
          details: [
            r.form_name,
            r.location != null ? r.location : "—",
            r.created_by ? `By: ${r.created_by}` : null,
            r.description ?? null,
          ]
            .filter((v) => v != null && v !== "")
            .join(" | "),
          ip: null,
          // Pass through full view fields so table can show all data in separate columns
          user_id: r.user_id != null ? String(r.user_id) : "—",
          form_name: r.form_name ?? "—",
          form_type: r.form_type ?? "—",
          description: r.description ?? "—",
          created_by: r.created_by ?? "—",
          location: r.location != null ? r.location : "—",
        }));
        setActivities(list);
      } else if (activeSection === "audit") {
        // Fetch joined audit logs (audits + audit_logs) so we show all main data
        const res = await axiosInstance.get(AUDIT_LOGS_JOINED_URL, {
          params: { limit: 1000 },
        });
        const data = res.data?.data;
        const rows = Array.isArray(data) ? data : [];
        const list = rows.map((r) => ({
          timestamp: formatTimestamp(r.status_changed_at),
          user: r.user_id != null ? `User #${r.user_id}` : "—",
          action: r.action ?? "AUDIT",
          type: "audit",
          details: [
            r.audit_id != null ? `Audit ID: ${r.audit_id}` : null,
            r.audit_name ? r.audit_name : null,
            r.action ? `Action: ${r.action}` : null,
          ]
            .filter((v) => v != null && v !== "")
            .join(" | "),
          // Pass through all main joined fields for table columns and search
          log_id: r.log_id,
          audit_id: r.audit_id,
          audit_name: r.audit_name ?? "—",
          auditor_id: r.auditor_id,
          auditor_name: r.auditor_name ?? "—",
          location: r.location_name ?? (r.location != null ? String(r.location) : "—"),
          audit_status_id: r.audit_status_id,
          audit_status_name: r.audit_status_name ?? "—",
          audit_created_at: formatTimestamp(r.audit_created_at),
          observed_at: formatTimestamp(r.observed_at),
          country_id: r.country_id,
          department_id: r.department_id,
          start_time: r.start_time != null ? String(r.start_time) : "—",
          end_time: r.end_time != null ? String(r.end_time) : "—",
          user_id: r.user_id != null ? String(r.user_id) : "—",
          co_auditors: r.co_auditors_names != null ? String(r.co_auditors_names).trim() : "—",
          auditees: r.auditees_names != null ? String(r.auditees_names).trim() : "—",
        }));
        setActivities(list);
      } else {
        const res = await axiosInstance.get(ACTIVITY_LOG_URL, {
          params: { limit: 1000 },
        });
        const data = res.data?.data;
        const list = Array.isArray(data) ? data : [];
        setActivities(list.filter((a) => (a.type || "").toLowerCase() !== "ticket"));
      }
    } catch (err) {
      setError(err.response?.data?.message || err.message || "Failed to load activity log");
      setActivities([]);
    } finally {
      setLoading(false);
    }
  }, [activeSection]);

  useEffect(() => {
    fetchActivities();
  }, [fetchActivities]);

  useEffect(() => {
    if (!loading && !error) {
      const interval = setInterval(fetchActivities, POLL_INTERVAL_MS);
      return () => clearInterval(interval);
    }
  }, [loading, error, fetchActivities]);

  const filteredActivities = useMemo(() => {
    const sectionTypeMap = { user: "user", forms: "form", audit: "audit" };
    const typeForSection = sectionTypeMap[activeSection];
    const searchLower = searchText.trim().toLowerCase();

    return activities.filter((activity) => {
      const user = String(activity.user ?? "").toLowerCase();
      const action = String(activity.action ?? "").toLowerCase();
      const details = String(activity.details ?? "").toLowerCase();
      const type = String(activity.type ?? "").toLowerCase();
      const userId = String(activity.user_id ?? "").toLowerCase();
      const formName = String(activity.form_name ?? "").toLowerCase();
      const description = String(activity.description ?? "").toLowerCase();
      const location = String(activity.location ?? "").toLowerCase();
      const createdBy = String(activity.created_by ?? "").toLowerCase();
      const auditName = String(activity.audit_name ?? "").toLowerCase();
      const auditStatusName = String(activity.audit_status_name ?? "").toLowerCase();
      const auditorName = String(activity.auditor_name ?? "").toLowerCase();
      const matchesSearch =
        !searchLower ||
        user.includes(searchLower) ||
        action.includes(searchLower) ||
        details.includes(searchLower) ||
        userId.includes(searchLower) ||
        formName.includes(searchLower) ||
        description.includes(searchLower) ||
        location.includes(searchLower) ||
        createdBy.includes(searchLower) ||
        auditName.includes(searchLower) ||
        auditStatusName.includes(searchLower) ||
        auditorName.includes(searchLower) ||
        (activity.co_auditors && String(activity.co_auditors).toLowerCase().includes(searchLower)) ||
        (activity.auditees && String(activity.auditees).toLowerCase().includes(searchLower));

      const matchesSection =
        typeForSection === "audit"
          ? type === "audit"
          : type === typeForSection;

      return matchesSearch && matchesSection;
    });
  }, [activities, searchText, activeSection]);

  const paginatedActivities = useMemo(() => {
    const start = (currentPage - 1) * entriesPerPage;
    const end = start + entriesPerPage;
    return filteredActivities.slice(start, end);
  }, [filteredActivities, currentPage, entriesPerPage]);

  const totalPages = Math.ceil(filteredActivities.length / entriesPerPage);

  const isFormLogsExport = activeSection === "forms" && filteredActivities.length > 0 && filteredActivities[0].form_name !== undefined;
  const isAuditLogsExport = activeSection === "audit" && filteredActivities.length > 0 && filteredActivities[0].audit_name !== undefined;
  const exportToCSV = () => {
    const headers = isFormLogsExport
      ? ["User", "User ID", "Form name", "Form type", "Description", "Created By", "Location", "Timestamp"]
      : isAuditLogsExport
        ? ["Timestamp", "User ID", "Action", "Audit ID", "Audit Name", "Site Name", "Auditor", "Co-auditors", "Auditees", "Audit Status", "Audit Created", "Observed At", "Start Time", "End Time"]
        : ["Timestamp", "User", "Action", "Type", "Details"];
    const rows = isFormLogsExport
      ? filteredActivities.map((a) => [
          a.user,
          a.user_id ?? "",
          a.form_name ?? "",
          a.form_type ?? "",
          a.description ?? "",
          a.created_by ?? "",
          a.location ?? "",
          a.timestamp,
        ])
      : isAuditLogsExport
        ? filteredActivities.map((a) => [
            a.timestamp ?? "",
            a.user_id ?? "",
            a.action ?? "",
            a.audit_id ?? "",
            a.audit_name ?? "",
            a.location ?? "",
            a.auditor_name ?? "",
            a.co_auditors ?? "",
            a.auditees ?? "",
            a.audit_status_name ?? "",
            a.audit_created_at ?? "",
            a.observed_at ?? "",
            a.start_time ?? "",
            a.end_time ?? "",
          ])
        : filteredActivities.map((a) => [
            a.timestamp,
            a.user,
            a.action,
            a.type,
            a.details,
          ]);
    const csv = [headers, ...rows]
      .map((row) => row.map((cell) => `"${cell}"`).join(","))
      .join("\n");

    const blob = new Blob([csv], { type: "text/csv" });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `activity-log-${new Date().toISOString().split("T")[0]}.csv`;
    a.click();
    window.URL.revokeObjectURL(url);
  };

  const handleRefresh = () => {
    setLoading(true);
    fetchActivities();
  };

  const handleEntriesPerPageChange = (e) => {
    setEntriesPerPage(parseInt(e.target.value));
    setCurrentPage(1);
  };

  const handleSearchChange = (e) => {
    setSearchText(e.target.value);
    setCurrentPage(1);
  };

  useEffect(() => {
    setCurrentPage(1);
  }, [activeSection]);

  if (loading && activities.length === 0) {
    return (
      <div className="activity-log-container">
        <div className="activity-log-section">
          <div className="activity-log-loading">
            <div className="activity-log-loading-spinner" />
            <p>Loading activity log…</p>
          </div>
        </div>
      </div>
    );
  }

  if (error && activities.length === 0) {
    return (
      <div className="activity-log-container">
        <div className="activity-log-section">
          <div className="activity-log-error">
            <p>{error}</p>
            <button type="button" className="activity-log-retry-btn" onClick={handleRefresh}>
              Retry
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="activity-log-container">
      <div className="activity-log-section">
        <ActivityLogHeader
          title={SECTION_LABELS[activeSection]}
          onExport={exportToCSV}
          onRefresh={handleRefresh}
          loading={loading}
          exportDisabled={filteredActivities.length === 0}
        />

        <ActivityLogControls
          entriesPerPage={entriesPerPage}
          searchText={searchText}
          onEntriesPerPageChange={handleEntriesPerPageChange}
          onSearchChange={handleSearchChange}
          viewMode={viewMode}
          onViewModeChange={setViewMode}
        />

        {viewMode === "list" ? (
          <ActivityLogTable activities={paginatedActivities} />
        ) : (
          <ActivityLogCards activities={paginatedActivities} />
        )}

        <Pagination
          currentPage={currentPage}
          totalPages={totalPages}
          totalEntries={filteredActivities.length}
          entriesPerPage={entriesPerPage}
          onPageChange={setCurrentPage}
        />
      </div>
    </div>
  );
};

export default ActivityLog;

