import { useState } from 'react';
import { Plus, Pencil, Trash2, RefreshCw, Copy, Check } from 'lucide-react';
import { toast } from 'sonner';
import Layout from '../../components/Layout';
import Modal from '../../components/Modal';
import { User, Role } from '../../types';
import { useAuth } from '../../contexts/AuthContext';
import {
  useUsers,
  useCreateUser,
  useUpdateUser,
  useDeleteUser,
} from '../../api/queries';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';

interface UserForm {
  username: string;
  email: string;
  displayName: string;
  password: string;
  role: Role;
}

const BLANK_FORM: UserForm = {
  username: '',
  email: '',
  displayName: '',
  password: '',
  role: 'AGENT',
};

const ROLE_LABELS: Record<Role, string> = {
  ADMIN: 'Admin',
  AGENT: 'Agent',
  USER: 'User',
  SERVICE: 'Service',
};

const ROLE_BADGE: Record<Role, string> = {
  ADMIN: 'bg-purple-500/20 text-purple-400 border-purple-500/30',
  AGENT: 'bg-blue-500/20 text-blue-400 border-blue-500/30',
  USER: 'bg-gray-500/20 text-gray-400 border-gray-500/30',
  SERVICE: 'bg-orange-500/20 text-orange-400 border-orange-500/30',
};

const ROLE_DESCRIPTIONS: Record<Role, string> = {
  ADMIN: 'Full access — manage users, CTI config, close and delete tickets',
  AGENT: 'Manage tickets — create, update, assign, comment, change status',
  USER: 'Basic access — view tickets and add comments only',
  SERVICE: 'Automation account — authenticates via API key, no password login',
};

export default function AdminUsers() {
  const { user: authUser } = useAuth();
  const { data: users = [] } = useUsers();
  const createUser = useCreateUser();
  const updateUser = useUpdateUser();
  const deleteUser = useDeleteUser();

  const [modal, setModal] = useState<'add' | 'edit' | null>(null);
  const [selected, setSelected] = useState<User | null>(null);
  const [form, setForm] = useState<UserForm>(BLANK_FORM);
  const [error, setError] = useState('');
  const [copiedKey, setCopiedKey] = useState<string | null>(null);
  const [newApiKey, setNewApiKey] = useState<string | null>(null);
  const [deleting, setDeleting] = useState<User | null>(null);
  const [rotating, setRotating] = useState<User | null>(null);

  const submitting = createUser.isPending || updateUser.isPending;

  const openAdd = () => {
    setForm(BLANK_FORM);
    setError('');
    setNewApiKey(null);
    setModal('add');
  };

  const openEdit = (u: User) => {
    setSelected(u);
    setForm({
      username: u.username,
      email: u.email,
      displayName: u.displayName,
      password: '',
      role: u.role,
    });
    setError('');
    setNewApiKey(null);
    setModal('edit');
  };

  const closeModal = () => {
    setModal(null);
    setSelected(null);
    setNewApiKey(null);
  };

  const handleAdd = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    try {
      const payload: Record<string, string> = {
        username: form.username,
        email: form.email,
        displayName: form.displayName,
        role: form.role,
      };
      if (form.password) payload.password = form.password;
      const created = await createUser.mutateAsync(payload);
      if (created.apiKey) setNewApiKey(created.apiKey);
      else closeModal();
    } catch (err: unknown) {
      const e = err as { response?: { data?: { error?: string } } };
      setError(e.response?.data?.error ?? 'Failed to create user');
    }
  };

  const handleEdit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!selected) return;
    setError('');
    try {
      const payload: Record<string, string> = {
        email: form.email,
        displayName: form.displayName,
        role: form.role,
      };
      if (form.password) payload.password = form.password;
      await updateUser.mutateAsync({ id: selected.id, data: payload });
      closeModal();
    } catch (err: unknown) {
      const e = err as { response?: { data?: { error?: string } } };
      setError(e.response?.data?.error ?? 'Failed to update user');
    }
  };

  const confirmDelete = async () => {
    if (!deleting) return;
    try {
      await deleteUser.mutateAsync(deleting.id);
      toast.success(`Deleted ${deleting.displayName}`);
    } catch (e) {
      toast.error((e as Error).message || 'Failed to delete user');
    }
    setDeleting(null);
  };

  const confirmRegenerate = async () => {
    if (!rotating) return;
    try {
      const updated = await updateUser.mutateAsync({
        id: rotating.id,
        data: { regenerateApiKey: true },
      });
      setNewApiKey(updated.apiKey ?? null);
      setSelected(rotating);
      setModal('edit');
    } catch (e) {
      toast.error((e as Error).message || 'Failed to rotate key');
    }
    setRotating(null);
  };

  const copyToClipboard = (key: string) => {
    navigator.clipboard.writeText(key);
    setCopiedKey(key);
    setTimeout(() => setCopiedKey(null), 2000);
  };

  const inputClass =
    'w-full bg-gray-800 border border-gray-700 text-gray-100 placeholder-gray-500 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent';
  const labelClass = 'block text-sm font-medium text-gray-300 mb-1';

  return (
    <Layout
      title="Users"
      action={
        <button
          onClick={openAdd}
          className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg text-sm hover:bg-blue-700 transition-colors"
        >
          <Plus size={14} />
          Add User
        </button>
      }
    >
      <div className="bg-gray-900 border border-gray-800 rounded-xl overflow-hidden">
        <table className="w-full text-sm">
          <thead className="border-b border-gray-800">
            <tr>
              <th className="text-left px-5 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">
                User
              </th>
              <th className="text-left px-5 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">
                Username
              </th>
              <th className="text-left px-5 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">
                Role
              </th>
              <th className="text-left px-5 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">
                Email
              </th>
              <th className="px-5 py-3" />
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-800">
            {users.map((u) => (
              <tr key={u.id} className="hover:bg-gray-800/50">
                <td className="px-5 py-3 font-medium text-gray-100">{u.displayName}</td>
                <td className="px-5 py-3 text-gray-500 font-mono text-xs">{u.username}</td>
                <td className="px-5 py-3">
                  <span
                    className={`inline-flex px-2 py-0.5 rounded text-xs font-medium border ${ROLE_BADGE[u.role]}`}
                  >
                    {ROLE_LABELS[u.role]}
                  </span>
                </td>
                <td className="px-5 py-3 text-gray-400">{u.email}</td>
                <td className="px-5 py-3">
                  <div className="flex items-center justify-end gap-2">
                    {u.role === 'SERVICE' && (
                      <button
                        onClick={() => setRotating(u)}
                        className="text-gray-600 hover:text-gray-300 transition-colors"
                        title="Regenerate API key"
                      >
                        <RefreshCw size={14} />
                      </button>
                    )}
                    <button
                      onClick={() => openEdit(u)}
                      className="text-gray-600 hover:text-gray-300 transition-colors"
                    >
                      <Pencil size={14} />
                    </button>
                    {u.id !== authUser?.id && (
                      <button
                        onClick={() => setDeleting(u)}
                        className="text-gray-600 hover:text-red-400 transition-colors"
                      >
                        <Trash2 size={14} />
                      </button>
                    )}
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* Add / Edit Modal */}
      {modal && (
        <Modal
          title={modal === 'add' ? 'Add User' : `Edit ${selected?.displayName}`}
          onClose={closeModal}
        >
          {newApiKey ? (
            <div className="space-y-4">
              <div className="bg-amber-500/10 border border-amber-500/30 rounded-lg p-4">
                <p className="text-sm font-medium text-amber-400 mb-2">
                  API Key — copy it now, it won&apos;t be shown again
                </p>
                <div className="flex items-center gap-2">
                  <code className="flex-1 text-xs bg-gray-800 border border-gray-700 text-gray-300 rounded px-3 py-2 font-mono break-all">
                    {newApiKey}
                  </code>
                  <button
                    onClick={() => copyToClipboard(newApiKey)}
                    className="flex-shrink-0 text-amber-400 hover:text-amber-300 transition-colors"
                  >
                    {copiedKey === newApiKey ? <Check size={16} /> : <Copy size={16} />}
                  </button>
                </div>
              </div>
              <button
                onClick={closeModal}
                className="w-full bg-blue-600 text-white py-2 rounded-lg text-sm hover:bg-blue-700 transition-colors"
              >
                Done
              </button>
            </div>
          ) : (
            <form onSubmit={modal === 'add' ? handleAdd : handleEdit} className="space-y-4">
              {error && (
                <div className="bg-red-500/10 border border-red-500/30 text-red-400 text-sm px-3 py-2 rounded-lg">
                  {error}
                </div>
              )}

              {modal === 'add' && (
                <div>
                  <label className={labelClass}>Username</label>
                  <input
                    type="text"
                    value={form.username}
                    onChange={(e) => setForm((f) => ({ ...f, username: e.target.value }))}
                    required
                    className={inputClass}
                  />
                </div>
              )}

              <div>
                <label className={labelClass}>Display Name</label>
                <input
                  type="text"
                  value={form.displayName}
                  onChange={(e) => setForm((f) => ({ ...f, displayName: e.target.value }))}
                  required
                  className={inputClass}
                />
              </div>

              <div>
                <label className={labelClass}>Email</label>
                <input
                  type="email"
                  value={form.email}
                  onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))}
                  required
                  className={inputClass}
                />
              </div>

              <div>
                <label className={labelClass}>
                  Password{' '}
                  {modal === 'edit' && (
                    <span className="text-gray-500 font-normal">(leave blank to keep current)</span>
                  )}
                </label>
                <input
                  type="password"
                  value={form.password}
                  onChange={(e) => setForm((f) => ({ ...f, password: e.target.value }))}
                  required={modal === 'add' && form.role !== 'SERVICE'}
                  className={inputClass}
                  placeholder={modal === 'edit' ? '••••••••' : ''}
                />
              </div>

              <div>
                <label className={labelClass}>Role</label>
                <select
                  value={form.role}
                  onChange={(e) => setForm((f) => ({ ...f, role: e.target.value as Role }))}
                  className={inputClass}
                >
                  <option value="AGENT">Agent</option>
                  <option value="USER">User</option>
                  <option value="ADMIN">Admin</option>
                  <option value="SERVICE">Service</option>
                </select>
                <p className="mt-1.5 text-xs text-gray-500">{ROLE_DESCRIPTIONS[form.role]}</p>
              </div>

              <div className="flex justify-end gap-3 pt-1">
                <button
                  type="button"
                  onClick={closeModal}
                  className="px-4 py-2 text-sm text-gray-400 border border-gray-700 rounded-lg hover:bg-gray-800 transition-colors"
                >
                  Cancel
                </button>
                <button
                  type="submit"
                  disabled={submitting}
                  className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 transition-colors"
                >
                  {submitting ? 'Saving...' : modal === 'add' ? 'Create User' : 'Save Changes'}
                </button>
              </div>
            </form>
          )}
        </Modal>
      )}

      <AlertDialog open={!!deleting} onOpenChange={(o) => !o && setDeleting(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete {deleting?.displayName}?</AlertDialogTitle>
            <AlertDialogDescription>
              This user will be permanently removed. Their tickets and comments are preserved.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={confirmDelete}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog open={!!rotating} onOpenChange={(o) => !o && setRotating(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Regenerate API key for {rotating?.displayName}?</AlertDialogTitle>
            <AlertDialogDescription>
              The old key will stop working immediately. You&apos;ll see the new key once — make
              sure whatever uses it can be updated.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={confirmRegenerate}>Rotate key</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </Layout>
  );
}
