"use client";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";
import { del, get } from "../../lib/api";
import ConfirmationDialog from "./ConfirmationDialog";
import LoadingCard from "./Loading";
import { useNotifications } from "./NotificationContext";
import Pagination from "./Pagination";
import SettingsCrud from "./SettingsCrud";

export default function SettingsList() {
  const queryClient = useQueryClient();
  const { addNotification } = useNotifications();
  const { data, isLoading, error } = useQuery({
    queryKey: ["settings"],
    queryFn: () => get("/config/settings")
  });

  // Listen for WebSocket events
  useEffect(() => {
    const handleSettingsUpdate = (event: CustomEvent) => {
      const settingsData = event.detail;
      if (settingsData.type === "settings") {
        // Invalidate and refetch settings when settings updates occur
        queryClient.invalidateQueries({ queryKey: ["settings"] });
      }
    };

    window.addEventListener(
      "settingsUpdate",
      handleSettingsUpdate as EventListener
    );

    return () => {
      window.removeEventListener(
        "settingsUpdate",
        handleSettingsUpdate as EventListener
      );
    };
  }, [queryClient]);

  const [editKey, setEditKey] = useState<string | null>(null);
  const [editValue, setEditValue] = useState<string>("");

  // Confirmation dialog state
  const [deleteConfirm, setDeleteConfirm] = useState<{
    isOpen: boolean;
    setting?: { key: string; value: any };
  }>({ isOpen: false });

  // State for filters and search
  const [searchTerm, setSearchTerm] = useState("");
  const [sortField, setSortField] = useState<"key" | "value">("key");
  const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");

  // Pagination state
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(25);

  const deleteMutation = useMutation({
    mutationFn: (key: string) => del(`/config/settings/${key}`),
    onSuccess: (_, key) => {
      queryClient.invalidateQueries({ queryKey: ["settings"] });
      toast.success("Setting deleted successfully");
      addNotification({
        type: "success",
        title: "Setting Deleted",
        message: `Setting "${key}" has been deleted successfully.`
      });
    },
    onError: (error, key) => {
      console.error("Failed to delete setting:", error);
      toast.error("Failed to delete setting");
      addNotification({
        type: "error",
        title: "Delete Failed",
        message: `Failed to delete setting "${key}". Please try again.`
      });
    }
  });

  const handleEdit = (key: string, value: any) => {
    setEditKey(key);
    setEditValue(JSON.stringify(value));
  };

  const handleEditClose = () => {
    setEditKey(null);
    setEditValue("");
  };

  // Confirmation dialog handlers
  const handleDeleteClick = (setting: { key: string; value: any }) => {
    setDeleteConfirm({
      isOpen: true,
      setting
    });
  };

  const handleDeleteConfirm = () => {
    if (deleteConfirm.setting) {
      deleteMutation.mutate(deleteConfirm.setting.key);
    }
    setDeleteConfirm({ isOpen: false });
  };

  const handleDeleteCancel = () => {
    setDeleteConfirm({ isOpen: false });
  };

  const truncateValue = (value: any) => {
    const str = JSON.stringify(value);
    return str.length > 50 ? str.substring(0, 50) + "..." : str;
  };

  const handleSort = (field: "key" | "value") => {
    if (sortField === field) {
      setSortDirection(sortDirection === "asc" ? "desc" : "asc");
    } else {
      setSortField(field);
      setSortDirection("asc");
    }
  };

  // Filter and sort data
  const filteredAndSortedData = useMemo(() => {
    if (!data) return [];

    const filtered = Object.entries(data).filter(
      ([key, value]: [string, any]) =>
        key.toLowerCase().includes(searchTerm.toLowerCase()) ||
        JSON.stringify(value).toLowerCase().includes(searchTerm.toLowerCase())
    );

    filtered.sort(
      ([aKey, aValue]: [string, any], [bKey, bValue]: [string, any]) => {
        let aValueStr = sortField === "key" ? aKey : JSON.stringify(aValue);
        let bValueStr = sortField === "key" ? bKey : JSON.stringify(bValue);

        aValueStr = aValueStr.toLowerCase();
        bValueStr = bValueStr.toLowerCase();

        if (aValueStr < bValueStr) return sortDirection === "asc" ? -1 : 1;
        if (aValueStr > bValueStr) return sortDirection === "asc" ? 1 : -1;
        return 0;
      }
    );

    return filtered;
  }, [data, searchTerm, sortField, sortDirection]);

  // Handle pagination
  const paginatedData = useMemo(() => {
    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return filteredAndSortedData.slice(startIndex, endIndex);
  }, [filteredAndSortedData, currentPage, pageSize]);

  // Reset to page 1 when filters change
  useEffect(() => {
    setCurrentPage(1);
  }, [searchTerm, sortField, sortDirection]);

  const displaySettings = paginatedData;

  if (isLoading) return <LoadingCard message="Loading settings..." />;
  if (error) {
    return (
      <div className="text-center p-8 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
        <div className="mb-6">
          <svg
            className="mx-auto h-16 w-16 text-red-400"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"
            />
          </svg>
        </div>
        <h2 className="text-xl font-semibold text-red-800 dark:text-red-200 mb-4">
          Failed to load settings
        </h2>
        <p className="text-gray-600 dark:text-gray-400 mb-6">
          There was an error loading the settings data.
        </p>
        <button
          onClick={() =>
            queryClient.invalidateQueries({ queryKey: ["settings"] })
          }
          className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
        >
          Try Again
        </button>
      </div>
    );
  }

  return (
    <>
      <div className="mb-6 p-4 border rounded bg-gray-50 dark:bg-gray-800">
        <div className="flex items-center justify-between mb-4">
          <h3 className="font-semibold">Settings</h3>
          <div className="flex items-center gap-2">
            <span className="text-sm text-gray-600 dark:text-gray-400">
              Total: {filteredAndSortedData.length} settings
            </span>
          </div>
        </div>

        {/* Filter Controls */}
        <div className="mb-4 space-y-4">
          {/* Search */}
          <div className="flex items-center gap-4">
            <div className="flex-1">
              <input
                type="text"
                placeholder="Search settings..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
              />
            </div>
          </div>
        </div>

        <div className="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-sm">
          <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
            <thead className="bg-gray-50 dark:bg-gray-800">
              <tr>
                <th
                  scope="col"
                  className="px-4 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-200 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700"
                  onClick={() => handleSort("key")}
                >
                  Key{" "}
                  {sortField === "key" && (sortDirection === "asc" ? "↑" : "↓")}
                </th>
                <th
                  scope="col"
                  className="px-4 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-200 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700"
                  onClick={() => handleSort("value")}
                >
                  Value{" "}
                  {sortField === "value" &&
                    (sortDirection === "asc" ? "↑" : "↓")}
                </th>
                <th
                  scope="col"
                  className="px-4 py-3 text-right text-xs font-semibold text-gray-700 dark:text-gray-200 uppercase tracking-wider"
                >
                  Actions
                </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-gray-200 dark:divide-gray-800">
              {displaySettings.length > 0 ? (
                displaySettings.map(([key, value]: [string, any]) => (
                  <tr key={key}>
                    <td className="px-4 py-2 whitespace-nowrap font-mono text-sm text-gray-900 dark:text-gray-100">
                      {key}
                    </td>
                    <td className="px-4 py-2 text-sm text-gray-900 dark:text-gray-100 max-w-xs truncate">
                      {truncateValue(value)}
                    </td>
                    <td className="px-4 py-2 whitespace-nowrap text-sm text-right">
                      <button
                        className="inline-flex items-center rounded-md bg-yellow-500 px-3 py-1 text-xs font-medium text-white shadow-sm hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2 mr-2"
                        onClick={() => handleEdit(key, value)}
                      >
                        Edit
                      </button>
                      <button
                        disabled={deleteMutation.isPending}
                        className="inline-flex items-center rounded-md bg-red-600 px-3 py-1 text-xs font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 disabled:opacity-50"
                        onClick={() => handleDeleteClick({ key, value })}
                      >
                        Delete
                      </button>
                    </td>
                  </tr>
                ))
              ) : (
                <tr>
                  <td
                    colSpan={3}
                    className="px-4 py-4 text-center text-gray-500 dark:text-gray-400"
                  >
                    No settings found matching your filters.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

      <Pagination
        currentPage={currentPage}
        totalItems={filteredAndSortedData.length}
        pageSize={pageSize}
        onPageChange={setCurrentPage}
        onPageSizeChange={(newPageSize) => {
          setPageSize(newPageSize);
          setCurrentPage(1);
        }}
      />

      {editKey && (
        <SettingsCrud
          editKey={editKey}
          editValue={editValue}
          onEditClose={handleEditClose}
        />
      )}

      <ConfirmationDialog
        isOpen={deleteConfirm.isOpen}
        title="Delete Setting"
        message={`Are you sure you want to delete setting "${deleteConfirm.setting?.key}"? This action cannot be undone.`}
        confirmText="Delete"
        cancelText="Cancel"
        type="danger"
        onConfirm={handleDeleteConfirm}
        onClose={handleDeleteCancel}
        isLoading={deleteMutation.isPending}
      />
    </>
  );
}
