'use client';

import Link from 'next/link';
import { useCallback, useEffect, useState } from 'react';
import Swal from 'sweetalert2';
import { RequireRole, useAuth } from '@/lib/auth-context';
import type { UserRole } from '@/lib/auth';
import {
  listUsers,
  ManagedUser,
  removeUser,
  resetUserPassword,
  ROLE_BADGES,
  ROLE_LABELS,
  updateUser,
} from '@/lib/services/users';
import UserFormModal from '@/components/app/UserFormModal';
import {
  EmptyState,
  ErrorAlert,
  Loading,
  PageHeader,
  Pagination,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

export default function UsuariosPage() {
  return (
    <RequireRole roles={['admin']}>
      <UsersView />
    </RequireRole>
  );
}

const PAGE_SIZE = 10;

type StatusFilter = '' | 'active' | 'inactive';

function UsersView() {
  const { user: currentUser } = useAuth();

  const [items, setItems] = useState<ManagedUser[]>([]);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const [term, setTerm] = useState('');
  const [role, setRole] = useState<UserRole | ''>('');
  const [status, setStatus] = useState<StatusFilter>('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<ManagedUser | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await listUsers({
        page,
        limit: PAGE_SIZE,
        search: term || undefined,
        role: role || undefined,
        isActive: status === '' ? undefined : status === 'active',
      });
      setItems(result.data);
      setTotal(result.total);
      setTotalPages(Math.max(result.totalPages, 1));
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, [page, term, role, status]);

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

  function isSelf(user: ManagedUser): boolean {
    return Number(user.id) === Number(currentUser?.id);
  }

  function handleSearch(e: React.FormEvent) {
    e.preventDefault();
    setPage(1);
    setTerm(search.trim());
  }

  function openCreate() {
    setEditing(null);
    setModalOpen(true);
  }

  function openEdit(user: ManagedUser) {
    setEditing(user);
    setModalOpen(true);
  }

  async function handleSaved() {
    const wasEdit = Boolean(editing);
    setModalOpen(false);
    setEditing(null);
    await Swal.fire({
      icon: 'success',
      title: wasEdit ? 'Usuário atualizado' : 'Usuário criado',
      timer: 1200,
      showConfirmButton: false,
    });
    load();
  }

  async function handleToggleActive(user: ManagedUser) {
    const activating = !user.isActive;
    const confirmation = await Swal.fire({
      icon: 'question',
      title: activating ? 'Reativar usuário?' : 'Desativar usuário?',
      text: activating
        ? `${user.email} poderá entrar no sistema novamente.`
        : `${user.email} não conseguirá mais entrar, e as sessões abertas serão encerradas.`,
      showCancelButton: true,
      confirmButtonText: activating ? 'Reativar' : 'Desativar',
      cancelButtonText: 'Cancelar',
      confirmButtonColor: activating ? undefined : '#dc3545',
    });
    if (!confirmation.isConfirmed) return;

    try {
      await updateUser(user.id, { isActive: activating });
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  async function handleResetPassword(user: ManagedUser) {
    const { value: newPassword } = await Swal.fire<string>({
      title: 'Redefinir senha',
      html:
        `<p class="mb-2">${escapeHtml(user.email)}</p>` +
        '<p class="small text-muted mb-0">As sessões abertas deste usuário serão encerradas.</p>',
      input: 'password',
      inputLabel: 'Nova senha (mínimo 8 caracteres)',
      inputAttributes: { autocomplete: 'new-password' },
      showCancelButton: true,
      confirmButtonText: 'Redefinir',
      cancelButtonText: 'Cancelar',
      inputValidator: (value) =>
        !value || value.length < 8
          ? 'A senha deve ter no mínimo 8 caracteres'
          : undefined,
    });
    if (!newPassword) return;

    try {
      await resetUserPassword(user.id, newPassword);
      Swal.fire({
        icon: 'success',
        title: 'Senha redefinida',
        timer: 1200,
        showConfirmButton: false,
      });
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  async function handleRemove(user: ManagedUser) {
    const confirmation = await Swal.fire({
      icon: 'warning',
      title: 'Excluir usuário?',
      text: `${user.email} perderá o acesso. Se for só uma pausa, prefira desativar.`,
      showCancelButton: true,
      confirmButtonText: 'Excluir',
      cancelButtonText: 'Cancelar',
      confirmButtonColor: '#dc3545',
    });
    if (!confirmation.isConfirmed) return;

    try {
      await removeUser(user.id);
      await Swal.fire({
        icon: 'success',
        title: 'Usuário excluído',
        timer: 1100,
        showConfirmButton: false,
      });
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  const filtered = Boolean(term || role || status);

  return (
    <>
      <PageHeader
        title="Usuários"
        subtitle="Contas de acesso ao painel e ao portal do paciente"
        action={
          <div className="d-flex gap-2">
            <Link href="/painel/permissoes" className="btn btn-outline-secondary">
              <i className="bi bi-shield-lock me-1" />
              Permissões
            </Link>
            <button type="button" className="btn btn-primary" onClick={openCreate}>
              <i className="bi bi-plus-lg me-1" />
              Novo usuário
            </button>
          </div>
        }
      />

      <form className="row g-2 mb-3" onSubmit={handleSearch}>
        <div className="col-12 col-md-5">
          <div className="input-group">
            <span className="input-group-text">
              <i className="bi bi-search" />
            </span>
            <input
              className="form-control"
              placeholder="Buscar por e-mail"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              aria-label="Buscar usuário"
            />
          </div>
        </div>
        <div className="col-6 col-md-2">
          <select
            className="form-select"
            aria-label="Filtrar por papel"
            value={role}
            onChange={(e) => {
              setPage(1);
              setRole(e.target.value as UserRole | '');
            }}
          >
            <option value="">Todos os papéis</option>
            {(Object.keys(ROLE_LABELS) as UserRole[]).map((r) => (
              <option key={r} value={r}>
                {ROLE_LABELS[r]}
              </option>
            ))}
          </select>
        </div>
        <div className="col-6 col-md-2">
          <select
            className="form-select"
            aria-label="Filtrar por status"
            value={status}
            onChange={(e) => {
              setPage(1);
              setStatus(e.target.value as StatusFilter);
            }}
          >
            <option value="">Todos os status</option>
            <option value="active">Ativos</option>
            <option value="inactive">Inativos</option>
          </select>
        </div>
        <div className="col-auto">
          <button className="btn btn-outline-primary" type="submit">
            Buscar
          </button>
        </div>
      </form>

      {error && <ErrorAlert message={error} onRetry={load} />}

      {loading ? (
        <Loading />
      ) : items.length === 0 ? (
        <EmptyState
          icon="bi-person-gear"
          title="Nenhum usuário encontrado"
          description={
            filtered
              ? 'Ajuste a busca ou os filtros e tente novamente.'
              : 'Cadastre o primeiro usuário.'
          }
        />
      ) : (
        <div className="card border-0 shadow-sm">
          <div className="table-responsive">
            <table className="table table-hover align-middle mb-0">
              <thead className="table-light">
                <tr>
                  <th scope="col">E-mail</th>
                  <th scope="col">Papel</th>
                  <th scope="col">Status</th>
                  <th scope="col">Último acesso</th>
                  <th scope="col">Criado em</th>
                  <th scope="col" className="text-end">Ações</th>
                </tr>
              </thead>
              <tbody>
                {items.map((user) => {
                  const self = isSelf(user);
                  return (
                    <tr key={user.id}>
                      <td className="fw-semibold">
                        {user.email}
                        {self && (
                          <span className="badge text-bg-light border ms-2">você</span>
                        )}
                      </td>
                      <td>
                        <span className={`badge ${ROLE_BADGES[user.role]}`}>
                          {ROLE_LABELS[user.role]}
                        </span>
                      </td>
                      <td>
                        {user.isActive ? (
                          <span className="badge text-bg-success">Ativo</span>
                        ) : (
                          <span className="badge text-bg-secondary">Inativo</span>
                        )}
                      </td>
                      <td className="text-muted">{formatDateTime(user.lastLoginAt)}</td>
                      <td className="text-muted">{formatDateTime(user.createdAt)}</td>
                      <td className="text-end table-nowrap">
                        <button
                          type="button"
                          className="btn btn-sm btn-outline-secondary"
                          onClick={() => openEdit(user)}
                          aria-label={`Editar ${user.email}`}
                          title="Editar"
                        >
                          <i className="bi bi-pencil" aria-hidden="true" />
                        </button>
                        <button
                          type="button"
                          className="btn btn-sm btn-outline-secondary ms-1"
                          onClick={() => handleResetPassword(user)}
                          aria-label={`Redefinir senha de ${user.email}`}
                          title="Redefinir senha"
                        >
                          <i className="bi bi-key" aria-hidden="true" />
                        </button>
                        {!self && (
                          <>
                            <button
                              type="button"
                              className={`btn btn-sm ms-1 ${
                                user.isActive
                                  ? 'btn-outline-warning'
                                  : 'btn-outline-success'
                              }`}
                              onClick={() => handleToggleActive(user)}
                              aria-label={`${user.isActive ? 'Desativar' : 'Reativar'} ${user.email}`}
                              title={user.isActive ? 'Desativar' : 'Reativar'}
                            >
                              <i
                                className={`bi ${user.isActive ? 'bi-person-slash' : 'bi-person-check'}`}
                                aria-hidden="true"
                              />
                            </button>
                            <button
                              type="button"
                              className="btn btn-sm btn-outline-danger ms-1"
                              onClick={() => handleRemove(user)}
                              aria-label={`Excluir ${user.email}`}
                              title="Excluir"
                            >
                              <i className="bi bi-trash" aria-hidden="true" />
                            </button>
                          </>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          <div className="card-body pt-0">
            <Pagination
              page={page}
              totalPages={totalPages}
              total={total}
              onChange={setPage}
            />
          </div>
        </div>
      )}

      <UserFormModal
        open={modalOpen}
        user={editing}
        isSelf={editing ? isSelf(editing) : false}
        onClose={() => {
          setModalOpen(false);
          setEditing(null);
        }}
        onSaved={handleSaved}
      />
    </>
  );
}

function escapeHtml(value: string): string {
  return value
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}
