"use client";

import { useState, useEffect, useMemo } from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { useSession } from "next-auth/react";
import { Input } from "@/components/ui/input";
import { MoreHorizontal, Trash, Edit, UserPlus } from "lucide-react";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { toast } from "@/components/ui/use-toast";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

interface User {
  id: string;
  username: string;
  firstName: string;
  lastName: string;
  email: string;
  createdTimestamp: number;
  roles: string[];
}

interface UsersTableProps {
  userRole?: string[];
}

// Constants for role names
const ROLES = {
  ADMIN: "Admin",
  TEACHER: "Teacher",
  STUDENT: "Students"
} as const;

const ITEMS_PER_PAGE = 10;

export function UsersTable({ userRole = [] }: UsersTableProps) {
  const { data: session, status } = useSession();
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [searchTerm, setSearchTerm] = useState("");
  const [newUserDialog, setNewUserDialog] = useState(false);
  const [editUserDialog, setEditUserDialog] = useState(false);
  const [selectedUser, setSelectedUser] = useState<User | null>(null);
  const [formData, setFormData] = useState({
    username: "",
    firstName: "",
    lastName: "",
    email: "",
    password: "",
    roles: [] as string[],
  });

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

  const fetchUsers = async () => {
    try {
      setLoading(true);
      const response = await fetch("/api/users");
      const data = await response.json();
      console.log("Fetched users:", data);
      console.log("Current user role:", session?.user?.role); // Debug log
      setUsers(data);
    } catch (error) {
      console.error("Error fetching users:", error);
      toast({
        title: "Erreur",
        description: "Erreur lors de la récupération des utilisateurs",
        variant: "destructive",
      });
    } finally {
      setLoading(false);
    }
  };

  const filterUsers = (users: User[]) => {
    console.log("Filtering users with role:", userRole); // Debug log
    
    if (!Array.isArray(users)) return [];
    
    // If no role specified or user is admin, show all users
    if (!userRole?.length || userRole.includes(ROLES.ADMIN)) {
      console.log("Showing all users - admin or no role");
      return users;
    }
    
    // If user is teacher, show teachers and students
    if (userRole.includes(ROLES.TEACHER)) {
      console.log("Filtering for teacher view");
      return users.filter(user =>
        user.roles?.includes(ROLES.TEACHER) || user.roles?.includes(ROLES.STUDENT)
      );
    }
    
    // If user is student, show only students
    if (userRole.includes(ROLES.STUDENT)) {
      console.log("Filtering for student view");
      return users.filter(user => user.roles?.includes(ROLES.STUDENT));
    }
    
    // Default: show all users
    console.log("Default case: showing all users");
    return users;
  };

  const canDelete = (targetUserRole: string[]) => {
    if (!userRole?.length) return false;
    
    if (userRole.includes(ROLES.ADMIN)) return true;
    if (userRole.includes(ROLES.TEACHER)) {
      return targetUserRole.includes(ROLES.STUDENT);
    }
    return false;
  };

  const handleAddUser = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      const response = await fetch("/api/users", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(formData),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || "Erreur lors de la création de l'utilisateur");
      }

      setUsers(prev => [...prev, data.user]);
      setNewUserDialog(false);
      setFormData({
        username: "",
        firstName: "",
        lastName: "",
        email: "",
        password: "",
        roles: [],
      });
      
      toast({
        title: "Succès",
        description: "L'utilisateur a été créé avec succès",
      });
    } catch (error) {
      toast({
        title: "Erreur",
        description: error instanceof Error ? error.message : "Une erreur est survenue",
        variant: "destructive",
      });
    }
  };

  const handleEdit = async (userId: string) => {
    const user = users.find(u => u.id === userId);
    if (!user) return;

    setSelectedUser(user);
    setFormData({
      username: user.username,
      firstName: user.firstName || "",
      lastName: user.lastName || "",
      email: user.email || "",
      password: "",
      roles: user.roles || [],
    });
    setEditUserDialog(true);
  };

  const handleUpdateUser = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!selectedUser) return;

    try {
      const response = await fetch(`/api/users/${selectedUser.id}`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          firstName: formData.firstName,
          lastName: formData.lastName,
          email: formData.email,
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || "Erreur lors de la modification de l'utilisateur");
      }

      setUsers(prevUsers => prevUsers.map(u => 
        u.id === selectedUser.id ? { ...u, ...data } : u
      ));
      
      setEditUserDialog(false);
      setSelectedUser(null);
      
      toast({
        title: "Succès",
        description: "L'utilisateur a été modifié avec succès",
      });
    } catch (error) {
      toast({
        title: "Erreur",
        description: error instanceof Error ? error.message : "Une erreur est survenue",
        variant: "destructive",
      });
    }
  };

  const handleManageRoles = async (userId: string) => {
    const user = users.find(u => u.id === userId);
    if (!user) return;

    setSelectedUser(user);
    setFormData(prev => ({ ...prev, roles: user.roles || [] }));
    setEditUserDialog(true);
  };

  const handleUpdateRoles = async () => {
    if (!selectedUser) return;

    try {
      const response = await fetch(`/api/users/${selectedUser.id}/roles`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          roles: formData.roles,
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || "Erreur lors de la mise à jour des rôles");
      }

      setUsers(prevUsers => prevUsers.map(u => 
        u.id === selectedUser.id ? { ...u, roles: formData.roles } : u
      ));
      
      setEditUserDialog(false);
      setSelectedUser(null);
      
      toast({
        title: "Succès",
        description: "Les rôles ont été mis à jour avec succès",
      });
    } catch (error) {
      toast({
        title: "Erreur",
        description: error instanceof Error ? error.message : "Une erreur est survenue",
        variant: "destructive",
      });
    }
  };

  const handleDelete = async (userId: string) => {
    try {
      const response = await fetch(`/api/users/${userId}`, {
        method: "DELETE",
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || "Erreur lors de la suppression de l'utilisateur");
      }

      setUsers(prevUsers => prevUsers.filter(user => user.id !== userId));
      
      toast({
        title: "Succès",
        description: "L'utilisateur a été supprimé avec succès",
      });
    } catch (error) {
      toast({
        title: "Erreur",
        description: error instanceof Error ? error.message : "Une erreur est survenue",
        variant: "destructive",
      });
    }
  };

  const filteredUsers = useMemo(() => {
    let filtered = filterUsers(users);
    
    // Apply search filter
    if (searchTerm) {
      filtered = filtered.filter(user => 
        user.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
        user.email?.toLowerCase().includes(searchTerm.toLowerCase()) ||
        user.firstName?.toLowerCase().includes(searchTerm.toLowerCase()) ||
        user.lastName?.toLowerCase().includes(searchTerm.toLowerCase())
      );
    }
    
    return filtered;
  }, [users, searchTerm, userRole]);

  // Calculate pagination
  const totalPages = Math.ceil(filteredUsers.length / ITEMS_PER_PAGE);
  const paginatedUsers = filteredUsers.slice(
    (currentPage - 1) * ITEMS_PER_PAGE,
    currentPage * ITEMS_PER_PAGE
  );

  const handlePageChange = (page: number) => {
    setCurrentPage(page);
  };

  // First, let's debug the roles
  console.log("Current session:", {
    role: session?.user?.role,
    isAdmin: session?.user?.role?.includes("Admin"),
    isTeacher: session?.user?.role?.includes("Teacher")
  });

  if (!session) return null;
  if (loading) return <div className="text-center p-4">Loading...</div>;

  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <Input
          type="text"
          placeholder="Rechercher un utilisateur..."
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
          className="max-w-sm"
        />
        <Dialog open={newUserDialog} onOpenChange={setNewUserDialog}>
          <DialogTrigger asChild>
            <Button>Ajouter un utilisateur</Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Nouvel utilisateur</DialogTitle>
            </DialogHeader>
            <form onSubmit={handleAddUser} className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="username">Nom d'utilisateur</Label>
                <Input
                  id="username"
                  value={formData.username}
                  onChange={(e) => setFormData(prev => ({ ...prev, username: e.target.value }))}
                  required
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="firstName">Prénom</Label>
                <Input
                  id="firstName"
                  value={formData.firstName}
                  onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="lastName">Nom</Label>
                <Input
                  id="lastName"
                  value={formData.lastName}
                  onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="email">Email</Label>
                <Input
                  id="email"
                  type="email"
                  value={formData.email}
                  onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
                  required
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="password">Mot de passe</Label>
                <Input
                  id="password"
                  type="password"
                  value={formData.password}
                  onChange={(e) => setFormData(prev => ({ ...prev, password: e.target.value }))}
                  required
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="roles">Rôles</Label>
                <Select
                  value={formData.roles[0] || ""}
                  onValueChange={(value) => setFormData(prev => ({ ...prev, roles: [value] }))}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Sélectionner un rôle" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value={ROLES.ADMIN}>Admin</SelectItem>
                    <SelectItem value={ROLES.TEACHER}>Enseignant</SelectItem>
                    <SelectItem value={ROLES.STUDENT}>Étudiant</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <Button type="submit" className="w-full">
                Créer l'utilisateur
              </Button>
            </form>
          </DialogContent>
        </Dialog>
      </div>

      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Nom d'utilisateur</TableHead>
            <TableHead>Prénom</TableHead>
            <TableHead>Nom</TableHead>
            <TableHead>Email</TableHead>
            <TableHead>Date d'inscription</TableHead>
            <TableHead>Rôles</TableHead>
            <TableHead className="text-right">Actions</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {paginatedUsers.map((user) => (
            <TableRow key={user.id}>
              <TableCell>{user.username}</TableCell>
              <TableCell>{user.firstName || "-"}</TableCell>
              <TableCell>{user.lastName || "-"}</TableCell>
              <TableCell>{user.email || "-"}</TableCell>
              <TableCell>
                {new Date(user.createdTimestamp).toLocaleDateString()}
              </TableCell>
              <TableCell>{(user.roles || []).join(", ") || "-"}</TableCell>
              <TableCell className="text-right">
                <DropdownMenu>
                  <DropdownMenuTrigger asChild>
                    <Button variant="ghost" className="h-8 w-8 p-0">
                      <span className="sr-only">Open menu</span>
                      <MoreHorizontal className="h-4 w-4" />
                    </Button>
                  </DropdownMenuTrigger>
                  <DropdownMenuContent align="end">
                    <DropdownMenuLabel>Actions</DropdownMenuLabel>
                    <DropdownMenuItem onClick={() => handleEdit(user.id)}>
                      <Edit className="mr-2 h-4 w-4" />
                      Modifier
                    </DropdownMenuItem>
                    <DropdownMenuItem onClick={() => handleManageRoles(user.id)}>
                      <UserPlus className="mr-2 h-4 w-4" />
                      Gérer les rôles
                    </DropdownMenuItem>
                    <DropdownMenuSeparator />
                    <DropdownMenuItem
                      className="text-red-600"
                      onClick={() => handleDelete(user.id)}
                    >
                      <Trash className="mr-2 h-4 w-4" />
                      Supprimer
                    </DropdownMenuItem>
                  </DropdownMenuContent>
                </DropdownMenu>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>

      <Dialog open={editUserDialog} onOpenChange={setEditUserDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Modifier l'utilisateur</DialogTitle>
          </DialogHeader>
          <form onSubmit={handleUpdateUser} className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="edit-firstName">Prénom</Label>
              <Input
                id="edit-firstName"
                value={formData.firstName}
                onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="edit-lastName">Nom</Label>
              <Input
                id="edit-lastName"
                value={formData.lastName}
                onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="edit-email">Email</Label>
              <Input
                id="edit-email"
                type="email"
                value={formData.email}
                onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="edit-roles">Rôles</Label>
              <Select
                value={formData.roles[0] || ""}
                onValueChange={(value) => setFormData(prev => ({ ...prev, roles: [value] }))}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Sélectionner un rôle" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={ROLES.ADMIN}>Admin</SelectItem>
                  <SelectItem value={ROLES.TEACHER}>Enseignant</SelectItem>
                  <SelectItem value={ROLES.STUDENT}>Étudiant</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex space-x-2">
              <Button type="submit" className="flex-1">
                Modifier
              </Button>
              <Button
                type="button"
                variant="outline"
                onClick={handleUpdateRoles}
                className="flex-1"
              >
                Mettre à jour les rôles
              </Button>
            </div>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}
