'use client';

import { useEffect, useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Modal } from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';
import type { UserRole } from '@/lib/auth';
import {
  createUser,
  ManagedUser,
  ROLE_LABELS,
  updateUser,
} from '@/lib/services/users';

const ROLES = Object.keys(ROLE_LABELS) as UserRole[];

const ROLE_HINTS: Record<UserRole, string> = {
  admin: 'Acesso total ao painel, inclusive usuários e páginas do site.',
  receptionist: 'Pacientes, agenda e consulta ao corpo clínico.',
  dentist: 'Pacientes, agenda, histórico clínico e o próprio perfil.',
  patient: 'Apenas o portal do paciente, com os próprios dados.',
};

function makeSchema(isEdit: boolean) {
  return z
    .object({
      email: z.string().trim().email('Informe um e-mail válido'),
      password: z.string(),
      confirmPassword: z.string(),
      role: z.enum(['admin', 'receptionist', 'dentist', 'patient'], {
        message: 'Selecione o papel',
      }),
      isActive: z.boolean(),
    })
    .superRefine((values, ctx) => {
      if (isEdit) return;
      if (values.password.length < 8) {
        ctx.addIssue({
          code: 'custom',
          path: ['password'],
          message: 'A senha deve ter no mínimo 8 caracteres',
        });
      } else if (values.password !== values.confirmPassword) {
        ctx.addIssue({
          code: 'custom',
          path: ['confirmPassword'],
          message: 'As senhas não conferem',
        });
      }
    });
}

type FormValues = z.infer<ReturnType<typeof makeSchema>>;

export default function UserFormModal({
  open,
  user,
  isSelf,
  onClose,
  onSaved,
}: {
  open: boolean;
  /** Ausente = criação */
  user?: ManagedUser | null;
  /** Usuário editando a própria conta: papel e status ficam bloqueados */
  isSelf: boolean;
  onClose: () => void;
  onSaved: (user: ManagedUser) => void;
}) {
  const isEdit = Boolean(user);
  const schema = useMemo(() => makeSchema(isEdit), [isEdit]);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const {
    register,
    handleSubmit,
    reset,
    watch,
    formState: { errors },
  } = useForm<FormValues>({ resolver: zodResolver(schema) });

  useEffect(() => {
    if (!open) return;
    setError(null);
    reset({
      email: user?.email ?? '',
      password: '',
      confirmPassword: '',
      role: user?.role ?? 'receptionist',
      isActive: user?.isActive ?? true,
    });
  }, [open, user, reset]);

  const role = watch('role');

  async function onSubmit(values: FormValues) {
    setSubmitting(true);
    setError(null);
    try {
      const saved = user
        ? await updateUser(user.id, {
            email: values.email,
            ...(isSelf ? {} : { role: values.role, isActive: values.isActive }),
          })
        : await createUser({
            email: values.email,
            password: values.password,
            role: values.role,
            isActive: values.isActive,
          });
      onSaved(saved);
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <Modal
      open={open}
      title={isEdit ? 'Editar usuário' : 'Novo usuário'}
      onClose={onClose}
      busy={submitting}
      footer={
        <>
          <button
            type="button"
            className="btn btn-outline-secondary"
            onClick={onClose}
            disabled={submitting}
          >
            Cancelar
          </button>
          <button
            type="submit"
            form="user-form"
            className="btn btn-primary"
            disabled={submitting}
          >
            {submitting ? (
              <span className="spinner-border spinner-border-sm me-2" />
            ) : (
              <i className="bi bi-check-lg me-1" />
            )}
            Salvar
          </button>
        </>
      }
    >
      <form id="user-form" onSubmit={handleSubmit(onSubmit)} noValidate>
        {error && (
          <div className="alert alert-danger py-2" role="alert">
            {error}
          </div>
        )}

        <div className="mb-3">
          <label htmlFor="user-email" className="form-label">
            E-mail *
          </label>
          <input
            id="user-email"
            type="email"
            autoComplete="off"
            className={`form-control ${errors.email ? 'is-invalid' : ''}`}
            {...register('email')}
          />
          {errors.email && (
            <div className="invalid-feedback">{errors.email.message}</div>
          )}
        </div>

        {!isEdit && (
          <div className="row g-3 mb-3">
            <div className="col-12 col-sm-6">
              <label htmlFor="user-password" className="form-label">
                Senha *
              </label>
              <input
                id="user-password"
                type="password"
                autoComplete="new-password"
                className={`form-control ${errors.password ? 'is-invalid' : ''}`}
                {...register('password')}
              />
              {errors.password && (
                <div className="invalid-feedback">{errors.password.message}</div>
              )}
            </div>
            <div className="col-12 col-sm-6">
              <label htmlFor="user-confirm" className="form-label">
                Confirmar senha *
              </label>
              <input
                id="user-confirm"
                type="password"
                autoComplete="new-password"
                className={`form-control ${errors.confirmPassword ? 'is-invalid' : ''}`}
                {...register('confirmPassword')}
              />
              {errors.confirmPassword && (
                <div className="invalid-feedback">
                  {errors.confirmPassword.message}
                </div>
              )}
            </div>
            <div className="col-12 form-text mt-1">Mínimo de 8 caracteres.</div>
          </div>
        )}

        <div className="mb-3">
          <label htmlFor="user-role" className="form-label">
            Papel *
          </label>
          <select
            id="user-role"
            className={`form-select ${errors.role ? 'is-invalid' : ''}`}
            disabled={isSelf}
            {...register('role')}
          >
            {ROLES.map((r) => (
              <option key={r} value={r}>
                {ROLE_LABELS[r]}
              </option>
            ))}
          </select>
          {errors.role && (
            <div className="invalid-feedback">{errors.role.message}</div>
          )}
          <div className="form-text">
            {isSelf
              ? 'Você não pode alterar o seu próprio papel.'
              : role && ROLE_HINTS[role]}
          </div>
        </div>

        <div className="form-check form-switch">
          <input
            id="user-active"
            type="checkbox"
            className="form-check-input"
            disabled={isSelf}
            {...register('isActive')}
          />
          <label htmlFor="user-active" className="form-check-label">
            Usuário ativo (pode entrar no sistema)
          </label>
        </div>
      </form>
    </Modal>
  );
}
