import React from 'react';
import {
  FormularioCreacion,
  TipoPregunta,
  TiposValidacion,
} from '@/types/create-formulario';
import SimpleInput from '@/components/input';
import Select, { Option } from '@/components/select';
import Button from '@/components/button';
import { GetEventoWithCuestionariosWithCupos } from '@/types/evento';
import { formatearRangoFechas } from '@/utils/date-utils';

interface Props {
  evento?: GetEventoWithCuestionariosWithCupos;
  formulario: FormularioCreacion;
  onChange: (formularioActualizado: FormularioCreacion) => void;
  tipo_eventos?: Option[];
}

const tipoPreguntaOpciones: TipoPregunta[] = [
  'Abierta (Respuesta corta)',
  'Abierta (Parrafo)',
  'Cerrada',
  'Multiple',
];

const tiposValidacion: TiposValidacion[] = [
  'correo',
  'correo_institucional',
  'telefono',
  'nombre',
  'apellidos',
  'genero',
  'entero',
  'decimal',
  'comunidad_alumno',
  'cuenta_alumno',
  'comunidad_trabajador',
  'cuenta_trabajador',
  'rfc',
];

type CampoPreguntaSimple =
  | 'titulo'
  | 'tipo'
  | 'validacion'
  | 'obligatoria'
  | 'limite';
type CampoPreguntaOpciones = 'opciones';

const tiposCuestionario = [
  { label: 'Registro', value: 1 },
  { label: 'Evaluación', value: 2 },
];

export default function FormularioEditor({
  formulario,
  onChange,
  evento,
  tipo_eventos,
}: Props) {
  function actualizarCampo<K extends keyof FormularioCreacion>(
    campo: K,
    valor: FormularioCreacion[K]
  ): void {
    const actualizado = { ...formulario, [campo]: valor };
    onChange(actualizado);
  }

  function handleUpdatePregunta(
    seccionIdx: number,
    preguntaIdx: number,
    campo: CampoPreguntaSimple | CampoPreguntaOpciones,
    valor:
      | string
      | boolean
      | TipoPregunta
      | TiposValidacion
      | number
      | { valor: string }[]
      | undefined
  ) {
    const actualizado = { ...formulario };
    const pregunta = actualizado.secciones[seccionIdx].preguntas[preguntaIdx];

    if (campo === 'opciones') {
      pregunta.opciones = valor as { valor: string }[];
    } else if (campo === 'titulo' && typeof valor === 'string') {
      pregunta.titulo = valor;
    } else if (campo === 'tipo' && typeof valor === 'string') {
      pregunta.tipo = valor as TipoPregunta;
    } else if (campo === 'validacion' || valor === undefined) {
      pregunta.validacion = valor as TiposValidacion | undefined;
    } else if (campo === 'obligatoria' && typeof valor === 'boolean') {
      pregunta.obligatoria = valor;
    } else if (campo === 'limite' && typeof valor === 'number') {
      pregunta.limite = valor;
    }

    onChange(actualizado);
  }

  const handleUpdateSeccion = (
    index: number,
    campo: 'titulo' | 'descripcion',
    valor: string
  ) => {
    const actualizado = { ...formulario };
    actualizado.secciones = actualizado.secciones.map((seccion, idx) =>
      idx === index ? { ...seccion, [campo]: valor } : seccion
    );
    onChange(actualizado);
  };

  const agregarSeccion = () => {
    const nuevaSeccion = {
      titulo: '',
      descripcion: '',
      preguntas: [],
    };
    onChange({
      ...formulario,
      secciones: [...formulario.secciones, nuevaSeccion],
    });
  };

  const eliminarSeccion = (index: number) => {
    const nuevas = [...formulario.secciones];
    nuevas.splice(index, 1);
    onChange({ ...formulario, secciones: nuevas });
  };

  const agregarPregunta = (seccionIdx: number) => {
    const nuevaPregunta = {
      titulo: '',
      tipo: 'Abierta (Respuesta corta)' as TipoPregunta,
      obligatoria: false,
      opciones: [],
    };
    const actualizado = { ...formulario };
    actualizado.secciones[seccionIdx].preguntas.push(nuevaPregunta);
    onChange(actualizado);
  };

  const eliminarPregunta = (seccionIdx: number, preguntaIdx: number) => {
    const actualizado = { ...formulario };
    actualizado.secciones[seccionIdx].preguntas.splice(preguntaIdx, 1);
    onChange(actualizado);
  };

  // Renderizar solo información básica del formulario
  const renderInformacionBasica = () => (
    <div className="p-4">
      <h4 className="mb-3">Información del Formulario</h4>

      <div className="row">
        <div className="col-md-8">
          <SimpleInput
            label="Nombre del Formulario"
            value={formulario.nombre_form}
            onChange={(e) => actualizarCampo('nombre_form', e.target.value)}
          />
        </div>

        <div className="col-md-4">
          <SimpleInput
            label="Cupo máximo"
            type="number"
            placeholder="Opcional"
            value={formulario.cupo_maximo || ''}
            onChange={(e) =>
              actualizarCampo('cupo_maximo', Number(e.target.value) || 0)
            }
          />
        </div>
      </div>

      <SimpleInput
        label="Descripción del Formulario"
        value={formulario.descripcion}
        onChange={(e) => actualizarCampo('descripcion', e.target.value)}
      />

      <div className="row">
        <div className="col-md-6">
          <SimpleInput
            label="Fecha de Inicio"
            type="datetime-local"
            value={formulario.fecha_inicio.slice(0, 16)}
            onChange={(e) => actualizarCampo('fecha_inicio', e.target.value)}
          />
        </div>
        <div className="col-md-6">
          <SimpleInput
            label="Fecha de Fin"
            type="datetime-local"
            value={formulario.fecha_fin.slice(0, 16)}
            onChange={(e) => actualizarCampo('fecha_fin', e.target.value)}
          />
        </div>
      </div>

      {evento && (
        <div className="alert alert-primary d-flex align-items-center">
          <i className="bi bi-info-circle-fill me-2"></i>
          <div>
            <strong>Evento:</strong> {evento.nombre_evento}
            <br />
            <small>
              Se realizará{' '}
              {formatearRangoFechas(evento.fecha_inicio, evento.fecha_fin)}
            </small>
          </div>
        </div>
      )}

      <SimpleInput
        label="Mensaje de correo"
        value={formulario.mensaje_correo || ''}
        onChange={(e) => actualizarCampo('mensaje_correo', e.target.value)}
        placeholder="Mensaje que se enviará al correo del participante al registrarse"
      />

      <div className="row">
        <div className="col-md-6">
          <Select
            label="Tipo de Cuestionario"
            value={formulario.id_tipo_cuestionario}
            onChange={(e) =>
              actualizarCampo('id_tipo_cuestionario', Number(e.target.value))
            }
            options={tiposCuestionario}
            placeholder="Selecciona un tipo"
          />
        </div>
        <div className="col-md-6">
          <Select
            label="Tipo de evento"
            value={formulario.id_tipo_evento}
            onChange={(e) =>
              actualizarCampo('id_tipo_evento', Number(e.target.value))
            }
            options={tipo_eventos!}
            placeholder="Selecciona un tipo"
          />
        </div>
      </div>
    </div>
  );

  // Renderizar secciones y preguntas
  const renderSeccionesYPreguntas = () => (
    <div className="mt-4">
      <div className="d-flex justify-content-between align-items-center mb-4">
        <h4 className="mb-0">Secciones y Preguntas</h4>
        <Button
          className="btn btn-success"
          onClick={agregarSeccion}
          icon="plus"
        >
          Agregar sección
        </Button>
      </div>

      {formulario.secciones.map((seccion, seccionIdx) => (
        <div key={seccionIdx} className="mb-4 p-3 border rounded bg-light">
          <div className="d-flex justify-content-between align-items-center mb-2">
            <h5 className="mb-0">Sección {seccionIdx + 1}</h5>
            <Button
              variant="danger"
              icon="trash"
              size="sm"
              outline
              onClick={() => eliminarSeccion(seccionIdx)}
            >
              Eliminar sección
            </Button>
          </div>

          <SimpleInput
            label="Título de la sección"
            value={seccion.titulo}
            onChange={(e) =>
              handleUpdateSeccion(seccionIdx, 'titulo', e.target.value)
            }
          />

          <SimpleInput
            label="Descripción de la sección"
            value={seccion.descripcion}
            onChange={(e) =>
              handleUpdateSeccion(seccionIdx, 'descripcion', e.target.value)
            }
          />

          {/* Preguntas */}
          {seccion.preguntas.map((pregunta, preguntaIdx) => (
            <div key={preguntaIdx} className="mb-3 p-3 border rounded bg-white">
              <div className="d-flex justify-content-between align-items-center mb-2">
                <h6 className="mb-0">Pregunta {preguntaIdx + 1}</h6>
                <Button
                  variant="danger"
                  icon="trash"
                  size="sm"
                  outline
                  onClick={() => eliminarPregunta(seccionIdx, preguntaIdx)}
                >
                  Eliminar
                </Button>
              </div>

              <SimpleInput
                label="Título de la pregunta"
                value={pregunta.titulo}
                onChange={(e) =>
                  handleUpdatePregunta(
                    seccionIdx,
                    preguntaIdx,
                    'titulo',
                    e.target.value
                  )
                }
              />

              <div className="row">
                <div className="col-md-6">
                  <Select
                    label="Tipo de pregunta"
                    value={pregunta.tipo}
                    onChange={(e) => {
                      const nuevoTipo = e.target.value as TipoPregunta;
                      handleUpdatePregunta(
                        seccionIdx,
                        preguntaIdx,
                        'tipo',
                        nuevoTipo
                      );

                      // Si cambia a un tipo cerrado y no tiene opciones, agregar opciones por defecto
                      if (
                        (nuevoTipo === 'Cerrada' || nuevoTipo === 'Multiple') &&
                        (!pregunta.opciones || pregunta.opciones.length === 0)
                      ) {
                        handleUpdatePregunta(
                          seccionIdx,
                          preguntaIdx,
                          'opciones',
                          [{ valor: '' }, { valor: '' }]
                        );
                      }
                    }}
                    options={tipoPreguntaOpciones.map((tipo) => ({
                      label: tipo,
                      value: tipo,
                    }))}
                  />
                </div>

                <div className="col-md-6">
                  <Select
                    label="Validación"
                    value={pregunta.validacion || ''}
                    onChange={(e) =>
                      handleUpdatePregunta(
                        seccionIdx,
                        preguntaIdx,
                        'validacion',
                        e.target.value || undefined
                      )
                    }
                    options={[
                      { label: 'Ninguna', value: '' },
                      ...tiposValidacion.map((v) => ({
                        label: v,
                        value: v,
                      })),
                    ]}
                  />
                </div>
              </div>

              <div className="form-check mb-2">
                <input
                  className="form-check-input"
                  type="checkbox"
                  checked={pregunta.obligatoria}
                  id={`obligatoria-${seccionIdx}-${preguntaIdx}`}
                  onChange={(e) =>
                    handleUpdatePregunta(
                      seccionIdx,
                      preguntaIdx,
                      'obligatoria',
                      e.target.checked
                    )
                  }
                />
                <label
                  className="form-check-label"
                  htmlFor={`obligatoria-${seccionIdx}-${preguntaIdx}`}
                >
                  ¿Es obligatoria?
                </label>
              </div>

              {(pregunta.tipo === 'Cerrada' ||
                pregunta.tipo === 'Multiple') && (
                <div className="mb-2">
                  <div className="d-flex justify-content-between align-items-center mb-2">
                    <label className="form-label mb-0">Opciones</label>
                    <Button
                      variant="success"
                      size="sm"
                      icon="plus"
                      outline
                      onClick={() => {
                        const nuevasOpciones = [...(pregunta.opciones || [])];
                        nuevasOpciones.push({ valor: '' });
                        handleUpdatePregunta(
                          seccionIdx,
                          preguntaIdx,
                          'opciones',
                          nuevasOpciones
                        );
                      }}
                    >
                      Agregar opción
                    </Button>
                  </div>
                  {(pregunta.opciones || []).map((op, opIdx) => (
                    <div key={opIdx} className="d-flex align-items-center mb-2">
                      <SimpleInput
                        value={op.valor}
                        onChange={(e) => {
                          const nuevasOpciones = [...(pregunta.opciones || [])];
                          nuevasOpciones[opIdx].valor = e.target.value;
                          handleUpdatePregunta(
                            seccionIdx,
                            preguntaIdx,
                            'opciones',
                            nuevasOpciones
                          );
                        }}
                        placeholder={`Opción ${opIdx + 1}`}
                        className={{
                          container: 'me-2 flex-grow-1 mb-0',
                          input: 'form-control',
                        }}
                      />
                      <Button
                        variant="danger"
                        size="sm"
                        icon="trash"
                        outline
                        onClick={() => {
                          const nuevasOpciones = [...(pregunta.opciones || [])];
                          nuevasOpciones.splice(opIdx, 1);
                          handleUpdatePregunta(
                            seccionIdx,
                            preguntaIdx,
                            'opciones',
                            nuevasOpciones
                          );
                        }}
                        disabled={pregunta.opciones?.length === 1}
                        title={
                          pregunta.opciones?.length === 1
                            ? 'Una pregunta cerrada debe tener al menos una opción'
                            : 'Eliminar opción'
                        }
                      />
                    </div>
                  ))}
                  {(!pregunta.opciones || pregunta.opciones.length === 0) && (
                    <div className="text-muted small">
                      <i className="bi bi-info-circle me-1"></i>
                      Esta pregunta cerrada no tiene opciones. Agrega al menos
                      una opción.
                    </div>
                  )}
                </div>
              )}
            </div>
          ))}

          <Button
            outline
            className="mt-2"
            size="sm"
            icon="plus"
            onClick={() => agregarPregunta(seccionIdx)}
          >
            Agregar pregunta
          </Button>
        </div>
      ))}
    </div>
  );

  return {
    informacionBasica: renderInformacionBasica,
    seccionesYPreguntas: renderSeccionesYPreguntas,
  };
}
