import React, { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { api } from '../api';
import { toast } from 'sonner';
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import { format } from 'date-fns';
import { Button } from '../components/ui/button';
import { Dialog } from '../components/ui/dialog';
import { Input } from '../components/ui/input';
import { Loader2, AlertTriangle, UserPlus, Pencil, Trash2 } from 'lucide-react';
import { cn } from '../lib/utils';

const userSchema = z.object({
  fullName: z.string().min(2, 'Full name is required'),
  email: z.string().email('Invalid email address'),
  role: z.enum(['admin', 'moderator']),
});

type UserFormData = z.infer<typeof userSchema>;

type User = UserFormData & { created_at: string };

const columnHelper = createColumnHelper<User>();

const UserForm = ({ user, onClose }: { user: User | null; onClose: () => void }) => {
  const queryClient = useQueryClient();
  const isEditing = !!user;

  const { register, handleSubmit, formState: { errors }, reset } = useForm<UserFormData>({
    resolver: zodResolver(userSchema),
    defaultValues: user ? { fullName: user.fullName, email: user.email, role: user.role } : { role: 'moderator' },
  });

  const mutation = useMutation({
    mutationFn: (data: UserFormData) => {
      return isEditing ? api.put(`/api/admin/users/${user.email}`, data) : api.post('/api/admin/users', data);
    },
    onSuccess: () => {
      toast.success(isEditing ? 'User updated successfully' : 'User created successfully');
      queryClient.invalidateQueries({ queryKey: ['adminUsers'] });
      onClose();
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.error || 'An error occurred');
    }
  });

  useEffect(() => {
    reset(user ? { fullName: user.fullName, email: user.email, role: user.role } : { role: 'moderator' });
  }, [user, reset]);

  const onSubmit = (data: UserFormData) => mutation.mutate(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <div>
        <label className="text-xs font-mono text-neutral-400">Full Name</label>
        <Input {...register('fullName')} className="mt-1" />
        {errors.fullName && <p className="text-red-400 text-sm mt-1">{errors.fullName.message}</p>}
      </div>
      <div>
        <label className="text-xs font-mono text-neutral-400">Email</label>
        <Input {...register('email')} disabled={isEditing} className="mt-1" />
        {errors.email && <p className="text-red-400 text-sm mt-1">{errors.email.message}</p>}
      </div>
      <div>
        <label className="text-xs font-mono text-neutral-400">Role</label>
        <select {...register('role')} className="w-full mt-1 p-2 bg-neutral-800 border border-neutral-700 rounded-md focus:ring-2 focus:ring-green-accent focus:border-green-accent outline-none">
          <option value="moderator">Moderator</option>
          <option value="admin">Admin</option>
        </select>
        {errors.role && <p className="text-red-400 text-sm mt-1">{errors.role.message}</p>}
      </div>
      <div className="flex justify-end gap-2 pt-4">
        <Button type="button" variant="outline" onClick={onClose}>Cancel</Button>
        <Button type="submit" disabled={mutation.isPending}>{mutation.isPending ? <Loader2 className="animate-spin h-4 w-4" /> : 'Save'}</Button>
      </div>
    </form>
  );
};

const UserManagementPage = () => {
  const [isFormOpen, setIsFormOpen] = useState(false);
  const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false);
  const [selectedUser, setSelectedUser] = useState<User | null>(null);
  const queryClient = useQueryClient();

  const { data: users, isLoading, isError } = useQuery<User[]>({
    queryKey: ['adminUsers'],
    queryFn: async () => {
      const res = await api.get('/api/admin/users');
      return res.data;
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (email: string) => api.delete(`/api/admin/users/${email}`),
    onSuccess: () => {
      toast.success('User deleted successfully');
      queryClient.invalidateQueries({ queryKey: ['adminUsers'] });
      setIsDeleteConfirmOpen(false);
      setSelectedUser(null);
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.error || 'Failed to delete user');
    }
  });

  const columns = [
    columnHelper.accessor('fullName', {
      header: 'User',
      cell: info => (
        <div className='flex flex-col'>
            <span className='font-medium text-neutral-100'>{info.getValue()}</span>
            <span className='text-xs text-neutral-400 font-mono'>{info.row.original.email}</span>
        </div>
      )
    }),
    columnHelper.accessor('role', {
      header: 'Role',
      cell: info => <span className={cn('px-2 py-1 text-xs rounded-full font-mono', info.getValue() === 'admin' ? 'bg-green-accent/10 text-green-accent' : 'bg-neutral-700 text-neutral-300')}>{info.getValue()}</span>,
    }),
    columnHelper.accessor('created_at', {
      header: 'Created',
      cell: info => <span className="text-neutral-400">{format(new Date(info.getValue()), 'MMM d, yyyy')}</span>,
    }),
    columnHelper.accessor('email', {
      header: 'Actions',
      id: 'actions',
      cell: ({ row }) => (
        <div className="flex gap-2">
          <Button variant="ghost" size="sm" onClick={() => { setSelectedUser(row.original); setIsFormOpen(true); }}>
            <Pencil className="h-4 w-4" />
          </Button>
          <Button variant="ghost" size="sm" className="text-red-500 hover:text-red-400 hover:bg-red-500/10" onClick={() => { setSelectedUser(row.original); setIsDeleteConfirmOpen(true); }}>
            <Trash2 className="h-4 w-4" />
          </Button>
        </div>
      ),
    }),
  ];

  const table = useReactTable({ data: users || [], columns, getCoreRowModel: getCoreRowModel() });

  return (
    <div>
      <Dialog
        isOpen={isFormOpen}
        onClose={() => { setIsFormOpen(false); setSelectedUser(null); }}
        title={selectedUser ? 'Edit User' : 'Create New User'}
        showCloseButton={false}
      >
        <UserForm user={selectedUser} onClose={() => { setIsFormOpen(false); setSelectedUser(null); }} />
      </Dialog>

      <Dialog
        isOpen={isDeleteConfirmOpen}
        onClose={() => { setIsDeleteConfirmOpen(false); setSelectedUser(null); }}
        title="Confirm Deletion"
        description={`Are you sure you want to delete the user ${selectedUser?.email}? This action cannot be undone.`}
        confirmText="Yes, Delete User"
        onConfirm={() => selectedUser && deleteMutation.mutate(selectedUser.email)}
      />

      <div className="flex justify-between items-center mb-8">
        <h1 className="text-3xl font-bold font-mono">User Management</h1>
        <Button onClick={() => { setSelectedUser(null); setIsFormOpen(true); }}>
          <UserPlus className="h-4 w-4 mr-2" />
          New User
        </Button>
      </div>

      <div className="bg-neutral-900 border border-neutral-800 rounded-lg overflow-hidden">
        {isLoading ? (
          <div className="flex items-center justify-center p-12"><Loader2 className="h-8 w-8 animate-spin text-green-accent" /></div>
        ) : isError ? (
          <div className="flex items-center text-red-400 p-8"><AlertTriangle className="h-5 w-5 mr-3" /><span>Failed to load users.</span></div>
        ) : (
          <table className="w-full text-sm">
            <thead className="bg-neutral-800/50">
              {table.getHeaderGroups().map(headerGroup => (
                <tr key={headerGroup.id}>
                  {headerGroup.headers.map(header => (
                    <th key={header.id} className="p-4 text-left font-mono text-neutral-400 uppercase tracking-wider">
                      {flexRender(header.column.columnDef.header, header.getContext())}
                    </th>
                  ))}
                </tr>
              ))}
            </thead>
            <tbody>
              {table.getRowModel().rows.map(row => (
                <tr key={row.id} className="border-b border-neutral-800 last:border-b-0 hover:bg-neutral-800/30 transition-colors">
                  {row.getVisibleCells().map(cell => (
                    <td key={cell.id} className="p-4">
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
};

export default UserManagementPage;
