import moment from "moment";
import { useQuery } from "@tanstack/react-query";
import { useState, useRef, useEffect } from "react";

import { uiSpendLogsCall } from "../networking";
import { DataTable } from "./table";
import { columns, LogEntry } from "./columns";
import { Row } from "@tanstack/react-table";

interface SpendLogsTableProps {
  accessToken: string | null;
  token: string | null;
  userRole: string | null;
  userID: string | null;
}

interface PaginatedResponse {
  data: LogEntry[];
  total: number;
  page: number;
  page_size: number;
  total_pages: number;
}

export default function SpendLogsTable({
  accessToken,
  token,
  userRole,
  userID,
}: SpendLogsTableProps) {
  const [searchTerm, setSearchTerm] = useState("");
  const [showFilters, setShowFilters] = useState(false);
  const [showColumnDropdown, setShowColumnDropdown] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize] = useState(50);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const filtersRef = useRef<HTMLDivElement>(null);
  const quickSelectRef = useRef<HTMLDivElement>(null);

  // New state variables for Start and End Time
  const [startTime, setStartTime] = useState<string>(
    moment().subtract(24, "hours").format("YYYY-MM-DDTHH:mm")
  );
  const [endTime, setEndTime] = useState<string>(
    moment().format("YYYY-MM-DDTHH:mm")
  );

  // Add these new state variables at the top with other useState declarations
  const [isCustomDate, setIsCustomDate] = useState(false);
  const [quickSelectOpen, setQuickSelectOpen] = useState(false);
  const [tempTeamId, setTempTeamId] = useState("");
  const [tempKeyHash, setTempKeyHash] = useState("");
  const [selectedTeamId, setSelectedTeamId] = useState("");
  const [selectedKeyHash, setSelectedKeyHash] = useState("");
  const [selectedFilter, setSelectedFilter] = useState("Team ID");

  // Close dropdown when clicking outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node)
      ) {
        setShowColumnDropdown(false);
      }
      if (
        filtersRef.current &&
        !filtersRef.current.contains(event.target as Node)
      ) {
        setShowFilters(false);
      }
      if (
        quickSelectRef.current &&
        !quickSelectRef.current.contains(event.target as Node)
      ) {
        setQuickSelectOpen(false);
      }
    }

    document.addEventListener("mousedown", handleClickOutside);
    return () =>
      document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const logs = useQuery<PaginatedResponse>({
    queryKey: [
      "logs",
      "table",
      currentPage,
      pageSize,
      startTime,
      endTime,
      selectedTeamId,
      selectedKeyHash,
    ],
    queryFn: async () => {
      if (!accessToken || !token || !userRole || !userID) {
        console.log("Missing required auth parameters");
        return {
          data: [],
          total: 0,
          page: 1,
          page_size: pageSize,
          total_pages: 0,
        };
      }

      // Convert times to UTC before formatting
      const formattedStartTime = moment(startTime).utc().format("YYYY-MM-DD HH:mm:ss");
      const formattedEndTime = isCustomDate 
        ? moment(endTime).utc().format("YYYY-MM-DD HH:mm:ss")
        : moment().utc().format("YYYY-MM-DD HH:mm:ss");

      return await uiSpendLogsCall(
        accessToken,
        selectedKeyHash || undefined,
        selectedTeamId || undefined,
        undefined,
        formattedStartTime,
        formattedEndTime,
        currentPage,
        pageSize
      );
    },
    enabled: !!accessToken && !!token && !!userRole && !!userID,
    refetchInterval: 5000,
    refetchIntervalInBackground: true,
  });

  if (!accessToken || !token || !userRole || !userID) {
    console.log(
      "got None values for one of accessToken, token, userRole, userID",
    );
    return null;
  }

  const filteredData =
    logs.data?.data?.filter((log) => {
      const matchesSearch =
        !searchTerm ||
        log.request_id.includes(searchTerm) ||
        log.model.includes(searchTerm) ||
        (log.user && log.user.includes(searchTerm));
      
      // No need for additional filtering since we're now handling this in the API call
      return matchesSearch;
    }) || [];

  // Add this function to handle manual refresh
  const handleRefresh = () => {
    logs.refetch();
  };

  // Add this function to format the time range display
  const getTimeRangeDisplay = () => {
    if (isCustomDate) {
      return `${moment(startTime).format('MMM D, h:mm A')} - ${moment(endTime).format('MMM D, h:mm A')}`;
    }
    
    const now = moment();
    const start = moment(startTime);
    const diffMinutes = now.diff(start, 'minutes');
    
    if (diffMinutes <= 15) return 'Last 15 Minutes';
    if (diffMinutes <= 60) return 'Last Hour';
    
    const diffHours = now.diff(start, 'hours');
    if (diffHours <= 4) return 'Last 4 Hours';
    if (diffHours <= 24) return 'Last 24 Hours';
    if (diffHours <= 168) return 'Last 7 Days';
    return `${start.format('MMM D')} - ${now.format('MMM D')}`;
  };

  return (
    <div className="w-full p-6">
      <div className="flex items-center justify-between mb-4">
        <h1 className="text-xl font-semibold">Request Logs</h1>
      </div>
      
      <div className="bg-white rounded-lg shadow">
        <div className="border-b px-6 py-4">
          <div className="flex flex-col md:flex-row items-start md:items-center justify-between space-y-4 md:space-y-0">
            <div className="flex flex-wrap items-center gap-3">
              <div className="relative w-64">
                <input
                  type="text"
                  placeholder="Search by Request ID"
                  className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                />
                <svg
                  className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
                  />
                </svg>
              </div>
              <div className="relative" ref={filtersRef}>
                <button
                  className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
                  onClick={() => setShowFilters(!showFilters)}
                >
                  <svg
                    className="w-4 h-4"
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
                    />
                  </svg>
                  Filter
                </button>

                {showFilters && (
                  <div className="absolute left-0 mt-2 w-[500px] bg-white rounded-lg shadow-lg border p-4 z-50">
                    <div className="flex flex-col gap-4">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-medium">Where</span>
                        <div className="relative">
                          <button
                            onClick={() => setShowColumnDropdown(!showColumnDropdown)}
                            className="px-3 py-1.5 border rounded-md bg-white text-sm min-w-[160px] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-left flex justify-between items-center"
                          >
                            {selectedFilter}
                            <svg
                              className="h-4 w-4 text-gray-500"
                              fill="none"
                              stroke="currentColor"
                              viewBox="0 0 24 24"
                            >
                              <path
                                strokeLinecap="round"
                                strokeLinejoin="round"
                                strokeWidth={2}
                                d="M19 9l-7 7-7-7"
                              />
                            </svg>
                          </button>
                          {showColumnDropdown && (
                            <div className="absolute left-0 mt-1 w-[160px] bg-white border rounded-md shadow-lg z-50">
                              {["Team ID", "Key Hash"].map((option) => (
                                <button
                                  key={option}
                                  className={`w-full px-3 py-2 text-left text-sm hover:bg-gray-50 flex items-center gap-2 ${
                                    selectedFilter === option
                                      ? "bg-blue-50 text-blue-600"
                                      : ""
                                  }`}
                                  onClick={() => {
                                    setSelectedFilter(option);
                                    setShowColumnDropdown(false);
                                    if (option === "Team ID") {
                                      setTempKeyHash("");
                                    } else {
                                      setTempTeamId("");
                                    }
                                  }}
                                >
                                  {selectedFilter === option && (
                                    <svg
                                      className="h-4 w-4 text-blue-600"
                                      fill="none"
                                      viewBox="0 0 24 24"
                                      stroke="currentColor"
                                    >
                                      <path
                                        strokeLinecap="round"
                                        strokeLinejoin="round"
                                        strokeWidth={2}
                                        d="M5 13l4 4L19 7"
                                      />
                                    </svg>
                                  )}
                                  {option}
                                </button>
                              ))}
                            </div>
                          )}
                        </div>
                        <input
                          type="text"
                          placeholder="Enter value..."
                          className="px-3 py-1.5 border rounded-md text-sm flex-1 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                          value={selectedFilter === "Team ID" ? tempTeamId : tempKeyHash}
                          onChange={(e) => {
                            if (selectedFilter === "Team ID") {
                              setTempTeamId(e.target.value);
                            } else {
                              setTempKeyHash(e.target.value);
                            }
                          }}
                        />
                        <button
                          className="p-1 hover:bg-gray-100 rounded-md"
                          onClick={() => {
                            setTempTeamId("");
                            setTempKeyHash("");
                          }}
                        >
                          <span className="text-gray-500">×</span>
                        </button>
                      </div>
                      
                      <div className="flex justify-end gap-2">
                        <button
                          className="px-3 py-1.5 text-sm border rounded-md hover:bg-gray-50"
                          onClick={() => {
                            setTempTeamId("");
                            setTempKeyHash("");
                            setShowFilters(false);
                          }}
                        >
                          Cancel
                        </button>
                        <button
                          className="px-3 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700"
                          onClick={() => {
                            setSelectedTeamId(tempTeamId);
                            setSelectedKeyHash(tempKeyHash);
                            setCurrentPage(1); // Reset to first page when applying new filters
                            setShowFilters(false);
                          }}
                        >
                          Apply Filters
                        </button>
                      </div>
                    </div>
                  </div>
                )}
              </div>

              <div className="flex items-center gap-2">
                <div className="relative" ref={quickSelectRef}>
                  <button
                    onClick={() => setQuickSelectOpen(!quickSelectOpen)}
                    className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
                  >
                    <svg
                      className="w-4 h-4"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
                      />
                    </svg>
                    {getTimeRangeDisplay()}
                  </button>

                  {quickSelectOpen && (
                    <div className="absolute right-0 mt-2 w-64 bg-white rounded-lg shadow-lg border p-2 z-50">
                      <div className="space-y-1">
                        {[
                          { label: "Last 15 Minutes", value: 15, unit: "minutes" },
                          { label: "Last Hour", value: 1, unit: "hours" },
                          { label: "Last 4 Hours", value: 4, unit: "hours" },
                          { label: "Last 24 Hours", value: 24, unit: "hours" },
                          { label: "Last 7 Days", value: 7, unit: "days" },
                        ].map((option) => (
                          <button
                            key={option.label}
                            className={`w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ${
                              getTimeRangeDisplay() === option.label ? 'bg-blue-50 text-blue-600' : ''
                            }`}
                            onClick={() => {
                              setEndTime(moment().format("YYYY-MM-DDTHH:mm"));
                              setStartTime(
                                moment()
                                  .subtract(option.value, option.unit as any)
                                  .format("YYYY-MM-DDTHH:mm")
                              );
                              setQuickSelectOpen(false);
                              setIsCustomDate(false);
                            }}
                          >
                            {option.label}
                          </button>
                        ))}
                        <div className="border-t my-2" />
                        <button
                          className={`w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ${
                            isCustomDate ? 'bg-blue-50 text-blue-600' : ''
                          }`}
                          onClick={() => setIsCustomDate(!isCustomDate)}
                        >
                          Custom Range
                        </button>
                      </div>
                    </div>
                  )}
                </div>
                
                <button
                  onClick={handleRefresh}
                  className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
                  title="Refresh data"
                >
                  <svg
                    className={`w-4 h-4 ${logs.isFetching ? 'animate-spin' : ''}`}
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
                    />
                  </svg>
                  <span>Refresh</span>
                </button>
              </div>

              {isCustomDate && (
                <div className="flex items-center gap-2">
                  <div>
                    <input
                      type="datetime-local"
                      value={startTime}
                      onChange={(e) => {
                        setStartTime(e.target.value);
                        setCurrentPage(1);
                      }}
                      className="px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                    />
                  </div>
                  <span className="text-gray-500">to</span>
                  <div>
                    <input
                      type="datetime-local"
                      value={endTime}
                      onChange={(e) => {
                        setEndTime(e.target.value);
                        setCurrentPage(1);
                      }}
                      className="px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                    />
                  </div>
                </div>
              )}
            </div>

            <div className="flex items-center space-x-4">
              <span className="text-sm text-gray-700">
                Showing{" "}
                {logs.isLoading
                  ? "..."
                  : logs.data
                  ? (currentPage - 1) * pageSize + 1
                  : 0}{" "}
                -{" "}
                {logs.isLoading
                  ? "..."
                  : logs.data
                  ? Math.min(currentPage * pageSize, logs.data.total)
                  : 0}{" "}
                of{" "}
                {logs.isLoading
                  ? "..."
                  : logs.data
                  ? logs.data.total
                  : 0}{" "}
                results
              </span>
              <div className="flex items-center space-x-2">
                <span className="text-sm text-gray-700">
                  Page {logs.isLoading ? "..." : currentPage} of{" "}
                  {logs.isLoading
                    ? "..."
                    : logs.data
                    ? logs.data.total_pages
                    : 1}
                </span>
                <button
                  onClick={() =>
                    setCurrentPage((p) => Math.max(1, p - 1))
                  }
                  disabled={logs.isLoading || currentPage === 1}
                  className="px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  Previous
                </button>
                <button
                  onClick={() =>
                    setCurrentPage((p) =>
                      Math.min(
                        logs.data?.total_pages || 1,
                        p + 1,
                      ),
                    )
                  }
                  disabled={
                    logs.isLoading ||
                    currentPage === (logs.data?.total_pages || 1)
                  }
                  className="px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  Next
                </button>
              </div>
            </div>
          </div>
        </div>
        <DataTable
          columns={columns}
          data={filteredData}
          renderSubComponent={RequestViewer}
          getRowCanExpand={() => true}
        />
      </div>
    </div>
  );
}

function RequestViewer({ row }: { row: Row<LogEntry> }) {
  const formatData = (input: any) => {
    if (typeof input === "string") {
      try {
        return JSON.parse(input);
      } catch {
        return input;
      }
    }
    return input;
  };

  return (
    <div className="p-6 bg-gray-50 space-y-6">
      {/* Combined Info Card */}
      <div className="bg-white rounded-lg shadow">
        <div className="p-4 border-b">
          <h3 className="text-lg font-medium ">Request Details</h3>
        </div>
        <div className="space-y-2 p-4 ">
          <div className="flex">
            <span className="font-medium w-1/3">Request ID:</span>
            <span>{row.original.request_id}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Api Key:</span>
            <span>{row.original.api_key}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Team ID:</span>
            <span>{row.original.team_id}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Model:</span>
            <span>{row.original.model}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Api Base:</span>
            <span>{row.original.api_base}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Call Type:</span>
            <span>{row.original.call_type}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Spend:</span>
            <span>{row.original.spend}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Total Tokens:</span>
            <span>{row.original.total_tokens}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Prompt Tokens:</span>
            <span>{row.original.prompt_tokens}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Completion Tokens:</span>
            <span>{row.original.completion_tokens}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Start Time:</span>
            <span>{row.original.startTime}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">End Time:</span>
            <span>{row.original.endTime}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Cache Hit:</span>
            <span>{row.original.cache_hit}</span>
          </div>
          <div className="flex">
            <span className="font-medium w-1/3">Cache Key:</span>
            <span>{row.original.cache_key}</span>
          </div>
          {row?.original?.requester_ip_address && (
            <div className="flex">
              <span className="font-medium w-1/3">Request IP Address:</span>
              <span>{row?.original?.requester_ip_address}</span>
            </div>
          )}
        </div>
      </div>

      {/* Request Card */}
      <div className="bg-white rounded-lg shadow">
        <div className="flex justify-between items-center p-4 border-b">
          <h3 className="text-lg font-medium">Request Tags</h3>
        </div>
        <pre className="p-4  text-wrap overflow-auto text-sm">
          {JSON.stringify(formatData(row.original.request_tags), null, 2)}
        </pre>
      </div>

      {/* Request Card */}
      <div className="bg-white rounded-lg shadow">
        <div className="flex justify-between items-center p-4 border-b">
          <h3 className="text-lg font-medium">Request</h3>
          {/* <div>
            <button className="mr-2 px-3 py-1 text-sm border rounded hover:bg-gray-50">
              Expand
            </button>
            <button className="px-3 py-1 text-sm border rounded hover:bg-gray-50">
              JSON
            </button>
          </div> */}
        </div>
        <pre className="p-4  text-wrap overflow-auto text-sm">
          {JSON.stringify(formatData(row.original.messages), null, 2)}
        </pre>
      </div>

      {/* Response Card */}
      <div className="bg-white rounded-lg shadow">
        <div className="flex justify-between items-center p-4 border-b">
          <h3 className="text-lg font-medium">Response</h3>
          <div>
            {/* <button className="mr-2 px-3 py-1 text-sm border rounded hover:bg-gray-50">
              Expand
            </button>
            <button className="px-3 py-1 text-sm border rounded hover:bg-gray-50">
              JSON
            </button> */}
          </div>
        </div>
        <pre className="p-4 text-wrap overflow-auto text-sm">
          {JSON.stringify(formatData(row.original.response), null, 2)}
        </pre>
      </div>

      {/* Metadata Card */}
      {row.original.metadata &&
        Object.keys(row.original.metadata).length > 0 && (
          <div className="bg-white rounded-lg shadow">
            <div className="flex justify-between items-center p-4 border-b">
              <h3 className="text-lg font-medium">Metadata</h3>
              {/* <div>
                <button className="px-3 py-1 text-sm border rounded hover:bg-gray-50">
                  JSON
                </button>
              </div> */}
            </div>
            <pre className="p-4 text-wrap  overflow-auto text-sm ">
              {JSON.stringify(row.original.metadata, null, 2)}
            </pre>
          </div>
        )}
    </div>
  );
}