import React, { useState, useEffect, useRef } from "react";
import { toast } from "react-toastify";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Dropdown } from "primereact/dropdown";
import { Button } from "@mui/joy";
import { Dialog } from "primereact/dialog";
import { authFetch } from "@/utils/authFetch";
import { confirmDialog, ConfirmDialog } from "primereact/confirmdialog";
import BreadcrumbNav from "./BreadcrumbNav";
import { API_URL } from "@/config";

const STATUS_OPTIONS = ["Queued", "Started", "Compressing", "Finished", "Failed"];
const TAR_BASE_URL = "https://codey.lol/m/m2"; // configurable prefix

export default function RequestManagement() {
  const [requests, setRequests] = useState([]);
  const [filterType, setFilterType] = useState(null);
  const [filterStatus, setFilterStatus] = useState(null);
  const [filteredRequests, setFilteredRequests] = useState([]);
  const [selectedRequest, setSelectedRequest] = useState(null);
  const [isDialogVisible, setIsDialogVisible] = useState(false);
  const pollingRef = useRef(null);
  const pollingDetailRef = useRef(null);


  const tarballUrl = (absPath, quality) => {
    if (!absPath) return null;
    const filename = absPath.split("/").pop(); // get "SOMETHING.tar.gz"
    return `${TAR_BASE_URL}/${quality}/${filename}`;
  };

  const fetchJobs = async () => {
    try {
      const res = await authFetch(`${API_URL}/trip/jobs/list`);
      if (!res.ok) throw new Error("Failed to fetch jobs");
      const data = await res.json();
      setRequests(Array.isArray(data.jobs) ? data.jobs : []);
    } catch (err) {
      console.error(err);
      if (!toast.isActive('fetch-fail-toast')) {
        toast.error("Failed to fetch jobs list", {
          toastId: 'fetch-fail-toast',
        });
      }
    }
  };

  const fetchJobDetail = async (jobId) => {
    try {
      const res = await authFetch(`${API_URL}/trip/job/${jobId}`);
      if (!res.ok) throw new Error("Failed to fetch job details");
      return await res.json();
    } catch (err) {
      console.error(err);
      if (!toast.isActive('fetch-job-fail-toast')) {
        toast.error("Failed to fetch job details",
          {
            toastId: "fetch-job-fail-toast",
          });
      }
      return null;
    }
  };

  useEffect(() => { fetchJobs(); }, []);
  useEffect(() => {
    if (isDialogVisible && selectedRequest) {
      // Start polling
      const poll = async () => {
        const updated = await fetchJobDetail(selectedRequest.id);
        if (updated) setSelectedRequest(updated);
      };

      pollingDetailRef.current = setInterval(poll, 1500);

      return () => {
        if (pollingDetailRef.current) {
          clearInterval(pollingDetailRef.current);
          pollingDetailRef.current = null;
        }
      };
    }
  }, [isDialogVisible, selectedRequest?.id]);
  useEffect(() => {
    const hasActive = requests.some((j) => ["Queued", "Started", "Compressing"].includes(j.status));
    if (hasActive && !pollingRef.current) pollingRef.current = setInterval(fetchJobs, 1500);
    else if (!hasActive && pollingRef.current) {
      clearInterval(pollingRef.current);
      pollingRef.current = null;
    }
    return () => { if (pollingRef.current) clearInterval(pollingRef.current); pollingRef.current = null; };
  }, [requests]);

  useEffect(() => {
    const filtered = requests.filter((r) => {
      const typeMatch = !filterType || r.type === filterType;
      const statusMatch = filterStatus === "all" || filterStatus === null || r.status === filterStatus;
      return typeMatch && statusMatch;
    });
    setFilteredRequests(filtered);
  }, [filterType, filterStatus, requests]);


  const getStatusColorClass = (status) => {
    switch (status) {
      case "Queued": return "bg-yellow-700 text-white";
      case "Started": return "bg-blue-700 text-white";
      case "Compressing": return "bg-orange-700 text-white";
      case "Finished": return "bg-green-700 text-white";
      case "Failed": return "bg-red-700 text-white";
      default: return "bg-gray-700 text-white";
    }
  };

  const getQualityColorClass = (quality) => {
    switch (quality) {
      case "FLAC": return "bg-green-700 text-white";
      case "Lossy": return "bg-yellow-700 text-white";
      default: return "bg-gray-700 text-white";
    }
  };


  const statusBodyTemplate = (rowData) => (
    <span className={`inline-block px-3 py-1 rounded-full font-semibold text-sm ${getStatusColorClass(rowData.status)}`}>
      {rowData.status}
    </span>
  );

  const qualityBodyTemplate = (rowData) => (
    <span className={`inline-block px-3 py-1 rounded-full font-semibold text-sm ${getQualityColorClass(rowData.quality)}`}>
      {rowData.quality}
    </span>
  );


  const safeText = (val) => (val === 0 ? "0" : val || "—");
  const textWithEllipsis = (val, width = "12rem") => (
    <span className="truncate block" style={{ maxWidth: width }} title={val || ""}>{val || "—"}</span>
  );

  const truncate = (text, maxLen) =>
    maxLen <= 3
      ? text.slice(0, maxLen)
      : text.length <= maxLen
        ? text
        : text.slice(0, maxLen - 3) + '...';


  const basename = (p) => (typeof p === "string" ? p.split("/").pop() : "");

  const formatProgress = (p) => {
    if (p === null || p === undefined || p === "") return "—";
    const num = Number(p);
    if (Number.isNaN(num)) return "—";
    const pct = num > 1 ? Math.round(num) : num;
    return `${pct}%`;
  };

  const confirmDelete = (requestId) => {
    confirmDialog({
      message: "Are you sure you want to delete this request?",
      header: "Confirm Delete",
      icon: "pi pi-exclamation-triangle",
      accept: () => deleteRequest(requestId),
    });
  };

  const deleteRequest = (requestId) => {
    setRequests((prev) => prev.filter((r) => r.id !== requestId));
    toast.success("Request deleted");
  };

  const actionBodyTemplate = (rowData) => (
    <Button
      color="neutral"
      variant="outlined"
      size="sm"
      sx={{
        color: "#e5e7eb",
        borderColor: "#6b7280",
        '&:hover': { backgroundColor: '#374151', borderColor: '#9ca3af' },
      }}
      onClick={(e) => { e.stopPropagation(); confirmDelete(rowData.id); }}
    >
      Delete
    </Button>
  );

  const handleRowClick = async (e) => {
    const detail = await fetchJobDetail(e.data.id);
    if (detail) { setSelectedRequest(detail); setIsDialogVisible(true); }
  };

  return (

    <div className="w-max my-10 p-6 rounded-xl shadow-md
                bg-white dark:bg-neutral-900
                text-neutral-900 dark:text-neutral-100
                border border-neutral-200 dark:border-neutral-700
                sm:p-4 md:p-6">
      <style>{`
  /* Table and Dark Overrides */
  .p-datatable {
    table-layout: fixed !important;
  }
  .p-datatable td span.truncate {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  [data-theme="dark"] .p-datatable {
    background-color: #121212 !important;
    color: #e5e7eb !important;
  }
  [data-theme="dark"] .p-datatable-thead > tr > th {
    background-color: #1f1f1f !important;
    color: #e5e7eb !important;
    border-bottom: 1px solid #374151;
  }
  [data-theme="dark"] .p-datatable-tbody > tr {
    background-color: #1a1a1a !important;
    border-bottom: 1px solid #374151;
    color: #e5e7eb !important;
  }
  [data-theme="dark"] .p-datatable-tbody > tr:nth-child(odd) {
    background-color: #222 !important;
  }
  [data-theme="dark"] .p-datatable-tbody > tr:hover {
    background-color: #333 !important;
    color: #fff !important;
  }
  /* Paginator Dark Mode */
  [data-theme="dark"] .p-paginator {
    background-color: #121212 !important;
    color: #e5e7eb !important;
    border-top: 1px solid #374151 !important;
  }
  [data-theme="dark"] .p-paginator .p-paginator-page,
  [data-theme="dark"] .p-paginator .p-paginator-next,
  [data-theme="dark"] .p-paginator .p-paginator-prev,
  [data-theme="dark"] .p-paginator .p-paginator-first,
  [data-theme="dark"] .p-paginator .p-paginator-last {
    color: #e5e7eb !important;
    background: transparent !important;
    border: none !important;
  }
  [data-theme="dark"] .p-paginator .p-paginator-page:hover,
  [data-theme="dark"] .p-paginator .p-paginator-next:hover,
  [data-theme="dark"] .p-paginator .p-paginator-prev:hover {
    background-color: #374151 !important;
    color: #fff !important;
    border-radius: 0.25rem;
  }
  [data-theme="dark"] .p-paginator .p-highlight {
    background-color: #6b7280 !important;
    color: #fff !important;
    border-radius: 0.25rem !important;
  }
  
  /* Dark mode for PrimeReact Dialog */
[data-theme="dark"] .p-dialog {
  background-color: #1a1a1a !important;
  color: #e5e7eb !important;
  border-color: #374151 !important;
}

[data-theme="dark"] .p-dialog .p-dialog-header {
  background-color: #121212 !important;
  color: #e5e7eb !important;
  border-bottom: 1px solid #374151 !important;
}

[data-theme="dark"] .p-dialog .p-dialog-content {
  background-color: #1a1a1a !important;
  color: #e5e7eb !important;
}

[data-theme="dark"] .p-dialog .p-dialog-footer {
  background-color: #121212 !important;
  border-top: 1px solid #374151 !important;
  color: #e5e7eb !important;
}
`}</style>

      <BreadcrumbNav currentPage="management" />
      <h2 className="text-3xl font-semibold mt-0">Media Request Management</h2>

      <div className="flex flex-wrap gap-6 mb-6">
        <Dropdown
          value={filterStatus}
          options={[{ label: "All Statuses", value: "all" }, ...STATUS_OPTIONS.map((s) => ({ label: s, value: s }))]}
          onChange={(e) => setFilterStatus(e.value)}
          placeholder="Filter by Status"
          className="min-w-[180px]"
        />
      </div>

      <div className="w-max overflow-x-auto rounded-lg">
        <DataTable
          value={filteredRequests}
          paginator
          rows={10}
          removableSort
          sortMode="multiple"
          emptyMessage="No requests found."
          onRowClick={handleRowClick}
        >

          <Column
            field="id"
            header="ID"
            style={{ width: "6rem" }}
            body={(row) => (
              <span title={row.id}>
                {row.id.split("-").slice(-1)[0]}
              </span>
            )}
          />
          <Column field="target" header="Target" sortable style={{ width: "12rem" }} body={(row) => textWithEllipsis(row.target, "10rem")} />
          <Column field="tracks" header="# Tracks" style={{ width: "8rem" }} body={(row) => row.tracks} />
          <Column field="status" header="Status" body={statusBodyTemplate} style={{ width: "10rem", textAlign: "center" }} sortable />
          <Column field="progress" header="Progress" body={(row) => formatProgress(row.progress)} style={{ width: "8rem", textAlign: "center" }} sortable />
          <Column
            field="quality"
            header="Quality"
            body={qualityBodyTemplate}
            style={{ width: "6rem", textAlign: "center" }}
            sortable />
          <Column
            field="tarball"
            header={
              <span className="flex items-center">
                <i className="pi pi-download mr-1" /> {/* download icon in header */}
                Tarball
              </span>
            }
            body={(row) => {
              const url = tarballUrl(row.tarball, row.quality || "FLAC");
              const encodedURL = encodeURI(url);
              if (!url) return "—";

              const fileName = url.split("/").pop();

              return (
                <a
                  href={encodedURL}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="truncate text-blue-500 hover:underline"
                  title={fileName}
                >
                  {truncate(fileName, 16)}
                </a>
              );
            }}
            style={{ width: "10rem" }}
          />
        </DataTable>
      </div>

      <ConfirmDialog />

      <Dialog
        header="Request Details"
        visible={isDialogVisible}
        style={{ width: "500px" }}
        onHide={() => setIsDialogVisible(false)}
        breakpoints={{ "960px": "95vw" }}
        modal
        dismissableMask
        className="dark:bg-neutral-900 dark:text-neutral-100"
      >
        {selectedRequest ? (
          <div className="space-y-4 text-sm">

            {/* --- Metadata Card --- */}
            <div className="p-3 bg-gray-100 dark:bg-neutral-800 rounded-md grid grid-cols-2 gap-4">
              {selectedRequest.id && <p className="col-span-2 break-all"><strong>ID:</strong> {selectedRequest.id}</p>}
              {selectedRequest.target && <p><strong>Target:</strong> {selectedRequest.target}</p>}
              {selectedRequest.tracks && <p><strong># Tracks:</strong> {selectedRequest.tracks}</p>}
              {selectedRequest.quality && (
                <p>
                  <strong>Quality:</strong>{" "}
                  <span className={`px-2 py-0.5 rounded-full text-xs font-bold ${getQualityColorClass(selectedRequest.quality)}`}>
                    {selectedRequest.quality}
                  </span>
                </p>
              )}
            </div>

            {/* --- Status / Progress Card --- */}
            <div className="p-3 bg-gray-100 dark:bg-neutral-800 rounded-md grid grid-cols-2 gap-4">
              {selectedRequest.status && (
                <p>
                  <strong>Status:</strong>{" "}
                  <span className={`px-2 py-0.5 rounded-full text-xs font-bold ${getStatusColorClass(selectedRequest.status)}`}>
                    {selectedRequest.status}
                  </span>
                </p>
              )}
              {selectedRequest.progress !== undefined && selectedRequest.progress !== null && (
                <p><strong>Progress:</strong> {formatProgress(selectedRequest.progress)}</p>
              )}
            </div>

            {/* --- Timestamps Card --- */}
            <div className="p-3 bg-gray-100 dark:bg-neutral-800 rounded-md grid grid-cols-1 gap-2">
              {selectedRequest.enqueued_at && <p><strong>Enqueued:</strong> {new Date(selectedRequest.enqueued_at).toLocaleString()}</p>}
              {selectedRequest.started_at && <p><strong>Started:</strong> {new Date(selectedRequest.started_at).toLocaleString()}</p>}
              {selectedRequest.ended_at && <p><strong>Ended:</strong> {new Date(selectedRequest.ended_at).toLocaleString()}</p>}
            </div>

            {/* --- Tarball Card --- */}
            {
              selectedRequest.tarball && (
                <div className="p-3 bg-gray-100 dark:bg-neutral-800 rounded-md">
                  <p>
                    <strong>Tarball:</strong>{" "}
                    <a
                      href={encodeURI(tarballUrl(selectedRequest.tarball, selectedRequest.quality))}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-500 hover:underline"
                    >
                      {tarballUrl(selectedRequest.tarball, selectedRequest.quality).split("/").pop()}
                    </a>
                  </p>
                </div>
              )
            }

          </div >
        ) : (
          <p>Loading...</p>
        )
        }
      </Dialog >


    </div >
  );
}
