"use client";

import React, { useState, useMemo } from "react";
import { AgGridReact } from "ag-grid-react";
import { ColDef, ModuleRegistry, AllCommunityModule } from "ag-grid-community";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import { formatDate } from "@/lib/utils";

ModuleRegistry.registerModules([AllCommunityModule]);

function getTimeAgo(date: Date): string {
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  const diffHours = Math.floor(diffMins / 60);
  const diffDays = Math.floor(diffHours / 24);

  if (diffMins < 1) return "just now";
  if (diffMins < 60) return `${diffMins}m ago`;
  if (diffHours < 24) return `${diffHours}h ago`;
  return `${diffDays}d ago`;
}

interface User {
  id: string;
  email: string;
  firstName: string;
  lastName: string;
  role: string;
  phone?: string;
  gymId?: string;
  createdAt: Date;
  isCheckedIn?: boolean;
  checkInTime?: Date;
  client?: {
    id: string;
    membershipType: string;
    membershipStatus: string;
    joinDate: Date;
    lastVisit?: Date;
  };
}

interface UserGridProps {
  users: User[];
  onUserSelect?: (user: User) => void;
  onEditUser?: (user: User) => void;
  onDeleteUser?: (user: User) => void;
  onBulkDelete?: (users: User[]) => void;
  loading?: boolean;
}

export function UserGrid({
  users,
  onUserSelect,
  onEditUser,
  onDeleteUser,
  onBulkDelete,
  loading = false,
}: UserGridProps) {
  const [selectedUsers, setSelectedUsers] = useState<User[]>([]);
  const [searchQuery, setSearchQuery] = useState<string>("");
  const [gymNames, setGymNames] = useState<Record<string, string>>({});

  React.useEffect(() => {
    let isMounted = true;
    (async () => {
      try {
        const res = await fetch("/api/gyms");
        const data = await res.json();
        if (isMounted && Array.isArray(data)) {
          const map: Record<string, string> = {};
          for (const g of data) {
            if (g && g.id) {
              map[g.id] = g.name || g.id;
            }
          }
          setGymNames(map);
        }
      } catch (e) {
        // silently fail; we'll show gymId if name not available
      }
    })();
    return () => {
      isMounted = false;
    };
  }, []);

  const columnDefs: ColDef<User>[] = useMemo(
    () => [
      {
        headerName: "Name",
        valueGetter: (params) =>
          `${params.data?.firstName} ${params.data?.lastName}`,
        filter: "agTextColumnFilter",
        sortable: true,
        minWidth: 150,
      },
      {
        headerName: "Email",
        field: "email",
        filter: "agTextColumnFilter",
        sortable: true,
        minWidth: 200,
      },
      {
        headerName: "Role",
        field: "role",
        filter: "agTextColumnFilter",
        sortable: true,
        cellRenderer: (params: any) => {
          const roleColors = {
            superAdmin: "bg-red-100 text-red-800",
            admin: "bg-purple-100 text-purple-800",
            trainer: "bg-blue-100 text-blue-800",
            client: "bg-green-100 text-green-800",
          };
          const colorClass =
            roleColors[params.value as keyof typeof roleColors] ||
            "bg-gray-100 text-gray-800";

          const label =
            params.value === "superAdmin"
              ? "Super Admin"
              : params.value.charAt(0).toUpperCase() + params.value.slice(1);

          return (
            <span
              className={`px-2 py-1 rounded-full text-xs font-medium ${colorClass}`}
            >
              {label}
            </span>
          );
        },
        minWidth: 120,
      },
      {
        headerName: "Gym",
        field: "gymId",
        filter: "agTextColumnFilter",
        sortable: true,
        minWidth: 160,
        valueFormatter: (params: any) => {
          const gymId = params.value;
          if (!gymId) return "None";
          return gymNames[gymId] || gymId;
        },
      },

      {
        headerName: "Phone",
        field: "phone",
        filter: "agTextColumnFilter",
        sortable: true,
        minWidth: 130,
        valueFormatter: (params: any) => params.value || "N/A",
      },
      {
        headerName: "Membership",
        valueGetter: (params) => params.data?.client?.membershipType || "N/A",
        filter: "agTextColumnFilter",
        sortable: true,
        cellRenderer: (params: any) => {
          if (!params.value || params.value === "N/A")
            return <span className="text-gray-400">N/A</span>;

          const membershipColors = {
            vip: "bg-yellow-100 text-yellow-800 border-yellow-200",
            premium: "bg-blue-100 text-blue-800 border-blue-200",
            basic: "bg-slate-100 text-slate-800 border-slate-200",
          };
          const colorClass =
            membershipColors[params.value as keyof typeof membershipColors] ||
            "bg-gray-100 text-gray-800";

          const label =
            params.value.charAt(0).toUpperCase() + params.value.slice(1);

          return (
            <span
              className={`px-2 py-1 rounded-full text-xs font-medium border ${colorClass}`}
            >
              {label}
            </span>
          );
        },
        minWidth: 120,
      },
      {
        headerName: "Status",
        valueGetter: (params) => params.data?.client?.membershipStatus || "N/A",
        filter: "agTextColumnFilter",
        sortable: true,
        cellRenderer: (params: any) => {
          if (!params.value || params.value === "N/A")
            return <span className="text-gray-400">N/A</span>;

          const statusColors = {
            active: "bg-green-100 text-green-800",
            inactive: "bg-red-100 text-red-800",
            suspended: "bg-orange-100 text-orange-800",
            expired: "bg-gray-100 text-gray-800",
          };
          const colorClass =
            statusColors[params.value as keyof typeof statusColors] ||
            "bg-gray-100 text-gray-800";

          const label =
            params.value.charAt(0).toUpperCase() + params.value.slice(1);

          return (
            <span
              className={`px-2 py-1 rounded-full text-xs font-medium ${colorClass}`}
            >
              {label}
            </span>
          );
        },
        minWidth: 120,
      },
      {
        headerName: "Currently Checked In",
        valueGetter: (params) => params.data?.isCheckedIn,
        filter: "agTextColumnFilter",
        sortable: true,
        cellRenderer: (params: any) => {
          if (!params.data?.isCheckedIn) {
            return <span className="text-gray-400">—</span>;
          }

          const checkInTime = params.data.checkInTime
            ? new Date(params.data.checkInTime)
            : null;
          const timeAgo = checkInTime ? getTimeAgo(checkInTime) : "";

          return (
            <span className="px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 border border-green-200">
              ✓ Checked In {timeAgo && `(${timeAgo})`}
            </span>
          );
        },
        minWidth: 180,
      },
      {
        headerName: "Join Date",
        valueGetter: (params) =>
          params.data?.client?.joinDate || params.data?.createdAt,
        filter: "agDateColumnFilter",
        sortable: true,
        valueFormatter: (params: any) => formatDate(new Date(params.value)),
        minWidth: 120,
      },
      {
        headerName: "Last Visit",
        valueGetter: (params) => params.data?.client?.lastVisit,
        filter: "agDateColumnFilter",
        sortable: true,
        valueFormatter: (params: any) =>
          params.value ? formatDate(new Date(params.value)) : "Never",
        minWidth: 120,
      },
    ],
    [],
  );

  const defaultColDef: ColDef = useMemo(
    () => ({
      flex: 1,
      resizable: true,
      floatingFilter: true,
      suppressMenu: true,
    }),
    [],
  );

  const gridRef = React.useRef<AgGridReact<User>>(null);

  const gridOptions = {
    theme: "legacy" as const,
    columnDefs,
    defaultColDef,
    rowData: users,
    rowSelection: "multiple" as const,
    onSelectionChanged: () => {
      const selectedNodes = gridRef.current?.api.getSelectedNodes();
      const selectedData =
        selectedNodes?.map((node) => node.data).filter((u): u is User => !!u) ||
        [];
      setSelectedUsers(selectedData);
      if (selectedData.length === 1 && onUserSelect) {
        onUserSelect(selectedData[0]);
      }
    },
    suppressRowClickSelection: false,
    animateRows: true,
    loading: loading,
    pagination: true,
    paginationPageSize: 20,
    paginationPageSizeSelector: [10, 20, 50, 100],
    quickFilterText: searchQuery,
  };

  const handleEdit = () => {
    if (selectedUsers.length === 1 && onEditUser) {
      onEditUser(selectedUsers[0]);
    }
  };

  const handleDelete = () => {
    if (selectedUsers.length === 1 && onDeleteUser) {
      onDeleteUser(selectedUsers[0]);
    }
  };

  const handleBulkDelete = () => {
    if (selectedUsers.length > 0 && onBulkDelete) {
      onBulkDelete(selectedUsers);
    }
  };

  return (
    <div>
      <div className="flex justify-between items-center mb-4">
        <input
          type="text"
          placeholder="Search users..."
          className="border border-gray-300 rounded px-4 py-2"
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
        />
        <div className="flex gap-2">
          <button
            className="bg-green-500 text-white px-4 py-2 rounded disabled:opacity-50"
            onClick={handleEdit}
            disabled={selectedUsers.length !== 1}
          >
            Edit User
          </button>
          <button
            className="bg-red-500 text-white px-4 py-2 rounded disabled:opacity-50"
            onClick={handleDelete}
            disabled={selectedUsers.length !== 1}
          >
            Delete User
          </button>
          <button
            className="bg-yellow-500 text-white px-4 py-2 rounded disabled:opacity-50"
            onClick={handleBulkDelete}
            disabled={selectedUsers.length === 0}
          >
            Bulk Delete
          </button>
        </div>
      </div>
      <div
        className="ag-theme-alpine"
        style={{ height: "600px", width: "100%" }}
      >
        <AgGridReact<User> {...gridOptions} ref={gridRef} />
      </div>
    </div>
  );
}
