'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import Swal from 'sweetalert2';
import { extractApiError } from '@/lib/api-client';
import {
  formatLongDate,
  formatTimeInZone,
  todayInZone,
} from '@/lib/datetime';
import { bookOnline, getAvailability } from '@/lib/services/appointments';
import { listDentists } from '@/lib/services/dentists';
import { listSpecialties } from '@/lib/services/specialties';
import type {
  AvailabilitySlot,
  Dentist,
  PublicBookingSummary,
  Specialty,
} from '@/lib/types';

const BROWSER_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
const FALLBACK_TZ = 'America/Sao_Paulo';

type Step = 1 | 2 | 3;

export default function AgendarPage() {
  const [step, setStep] = useState<Step>(1);

  const [dentists, setDentists] = useState<Dentist[]>([]);
  const [specialties, setSpecialties] = useState<Map<number, Specialty>>(
    new Map(),
  );
  const [loadingDentists, setLoadingDentists] = useState(true);
  const [loadError, setLoadError] = useState<string | null>(null);

  const [dentist, setDentist] = useState<Dentist | null>(null);
  const [timezone, setTimezone] = useState(FALLBACK_TZ);
  const [date, setDate] = useState<string>(() => todayInZone(BROWSER_TZ));
  const [slots, setSlots] = useState<AvailabilitySlot[]>([]);
  const [slotsLoading, setSlotsLoading] = useState(false);
  const [slot, setSlot] = useState<AvailabilitySlot | null>(null);

  const [fullName, setFullName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [cpf, setCpf] = useState('');
  const [reason, setReason] = useState('');
  const [consent, setConsent] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);

  const [result, setResult] = useState<PublicBookingSummary | null>(null);

  const activeDentists = useMemo(
    () => dentists.filter((d) => d.isActive),
    [dentists],
  );

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        const [dentistPage, specialtyPage] = await Promise.all([
          listDentists({ limit: 100 }),
          listSpecialties({ limit: 100 }),
        ]);
        if (!active) return;
        setDentists(dentistPage.data);
        setSpecialties(new Map(specialtyPage.data.map((s) => [s.id, s])));
      } catch (err) {
        if (active) setLoadError(extractApiError(err));
      } finally {
        if (active) setLoadingDentists(false);
      }
    })();
    return () => {
      active = false;
    };
  }, []);

  const loadSlots = useCallback(async (dentistId: number, day: string) => {
    setSlotsLoading(true);
    setSlot(null);
    try {
      const availability = await getAvailability(dentistId, day);
      setTimezone(availability.timezone);
      setSlots(availability.slots);
    } catch {
      setSlots([]);
    } finally {
      setSlotsLoading(false);
    }
  }, []);

  useEffect(() => {
    if (dentist) {
      loadSlots(dentist.id, date);
    }
  }, [dentist, date, loadSlots]);

  function chooseDentist(selected: Dentist) {
    setDentist(selected);
    setSlot(null);
    setStep(2);
  }

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault();
    setFormError(null);

    if (!dentist || !slot) {
      setFormError('Escolha um dentista e um horário.');
      return;
    }
    if (!consent) {
      setFormError('É necessário aceitar o tratamento de dados (LGPD).');
      return;
    }

    setSubmitting(true);
    try {
      const summary = await bookOnline({
        fullName: fullName.trim(),
        email: email.trim(),
        phone: phone.trim(),
        cpf: cpf.trim() || undefined,
        dentistId: dentist.id,
        startAt: slot.startAt,
        reason: reason.trim() || undefined,
        consent: 'true',
      });
      setResult(summary);
      setStep(3);
      await Swal.fire({
        icon: 'success',
        title: 'Consulta solicitada!',
        text: 'Entraremos em contato para confirmar.',
        timer: 2000,
        showConfirmButton: false,
      });
    } catch (err) {
      setFormError(extractApiError(err));
    } finally {
      setSubmitting(false);
    }
  }

  function reset() {
    setResult(null);
    setDentist(null);
    setSlot(null);
    setSlots([]);
    setStep(1);
    setReason('');
    setConsent(false);
  }

  return (
    <>
      <section className="df-hero py-4">
        <div className="container">
          <h1 className="h3 fw-bold mb-1">Agende sua consulta</h1>
          <p className="mb-0 opacity-75">
            Escolha o profissional, o melhor horário e pronto.
          </p>
        </div>
      </section>

      <div className="container py-4" style={{ maxWidth: 960 }}>
        <ol className="d-flex flex-wrap gap-3 list-unstyled mb-4">
          {[
            { n: 1, label: 'Dentista' },
            { n: 2, label: 'Data e horário' },
            { n: 3, label: 'Seus dados' },
          ].map((item) => (
            <li
              key={item.n}
              className={`d-flex align-items-center ${
                step >= item.n ? 'text-primary fw-semibold' : 'text-muted'
              }`}
            >
              <span
                className={`badge rounded-pill me-2 ${
                  step >= item.n ? 'text-bg-primary' : 'text-bg-light border'
                }`}
              >
                {item.n}
              </span>
              {item.label}
            </li>
          ))}
        </ol>

        {loadError && (
          <div className="alert alert-danger" role="alert">
            {loadError}
          </div>
        )}

        {/* Etapa 1 — Dentista */}
        {step === 1 && (
          <>
            {loadingDentists ? (
              <div className="text-center py-5">
                <span className="spinner-border text-primary" />
              </div>
            ) : activeDentists.length === 0 ? (
              <div className="alert alert-info">
                Nenhum profissional disponível no momento. Tente novamente mais
                tarde.
              </div>
            ) : (
              <div className="row g-3">
                {activeDentists.map((d) => (
                  <div className="col-12 col-md-6" key={d.id}>
                    <button
                      type="button"
                      className="card border-0 shadow-sm h-100 w-100 text-start df-card-hover p-0"
                      onClick={() => chooseDentist(d)}
                    >
                      <div className="card-body">
                        <div className="d-flex align-items-center mb-2">
                          <i className="bi bi-person-circle fs-2 text-primary me-2" />
                          <div>
                            <h2 className="h6 mb-0">{d.fullName}</h2>
                            <small className="text-muted">
                              CRO {d.cro}/{d.croState}
                            </small>
                          </div>
                        </div>
                        <div className="d-flex flex-wrap gap-1">
                          {d.specialties.map((s) => (
                            <span className="badge text-bg-light border" key={s.id}>
                              {s.name}
                            </span>
                          ))}
                        </div>
                      </div>
                    </button>
                  </div>
                ))}
              </div>
            )}
          </>
        )}

        {/* Etapa 2 — Data e horário */}
        {step === 2 && dentist && (
          <div className="card border-0 shadow-sm">
            <div className="card-body">
              <div className="d-flex justify-content-between align-items-center mb-3">
                <h2 className="h6 mb-0">
                  <i className="bi bi-person-badge me-1 text-primary" />
                  {dentist.fullName}
                </h2>
                <button
                  className="btn btn-sm btn-link text-decoration-none"
                  onClick={() => setStep(1)}
                >
                  Trocar dentista
                </button>
              </div>

              <div className="row g-3 align-items-end mb-3">
                <div className="col-12 col-sm-6">
                  <label className="form-label" htmlFor="bk-date">
                    Escolha o dia
                  </label>
                  <input
                    id="bk-date"
                    type="date"
                    className="form-control"
                    value={date}
                    min={todayInZone(timezone)}
                    onChange={(e) => setDate(e.target.value)}
                  />
                </div>
                <div className="col-12 col-sm-6">
                  <p className="text-muted small mb-2">
                    {formatLongDate(date)} · fuso {timezone}
                  </p>
                </div>
              </div>

              {slotsLoading ? (
                <div className="text-center py-4">
                  <span className="spinner-border text-primary" />
                </div>
              ) : slots.length === 0 ? (
                <div className="alert alert-info mb-0">
                  Não há horários de atendimento neste dia. Tente outra data.
                </div>
              ) : (
                <div className="d-flex flex-wrap gap-2">
                  {slots.map((s) => (
                    <button
                      key={s.startAt}
                      type="button"
                      className={`btn ${
                        slot?.startAt === s.startAt
                          ? 'btn-primary'
                          : 'btn-outline-primary'
                      }`}
                      disabled={!s.available}
                      onClick={() => setSlot(s)}
                    >
                      {s.time}
                    </button>
                  ))}
                </div>
              )}

              <div className="d-flex justify-content-end mt-4">
                <button
                  className="btn btn-primary"
                  disabled={!slot}
                  onClick={() => setStep(3)}
                >
                  Continuar
                  <i className="bi bi-arrow-right ms-1" />
                </button>
              </div>
            </div>
          </div>
        )}

        {/* Etapa 3 — Dados e envio */}
        {step === 3 && !result && dentist && slot && (
          <div className="card border-0 shadow-sm">
            <div className="card-body">
              <div className="alert alert-light border">
                <i className="bi bi-calendar-check me-1 text-primary" />
                <strong>{dentist.fullName}</strong> · {formatLongDate(date)} às{' '}
                {formatTimeInZone(slot.startAt, timezone)}
              </div>

              <form onSubmit={handleSubmit} noValidate>
                {formError && (
                  <div className="alert alert-danger py-2" role="alert">
                    {formError}
                  </div>
                )}
                <div className="row g-3">
                  <div className="col-12 col-md-6">
                    <label className="form-label" htmlFor="ob-name">
                      Nome completo *
                    </label>
                    <input
                      id="ob-name"
                      className="form-control"
                      value={fullName}
                      onChange={(e) => setFullName(e.target.value)}
                      minLength={3}
                      maxLength={180}
                      required
                    />
                  </div>
                  <div className="col-12 col-md-6">
                    <label className="form-label" htmlFor="ob-email">
                      E-mail *
                    </label>
                    <input
                      id="ob-email"
                      type="email"
                      className="form-control"
                      value={email}
                      onChange={(e) => setEmail(e.target.value)}
                      maxLength={255}
                      required
                    />
                  </div>
                  <div className="col-12 col-md-6">
                    <label className="form-label" htmlFor="ob-phone">
                      Telefone/WhatsApp *
                    </label>
                    <input
                      id="ob-phone"
                      className="form-control"
                      value={phone}
                      onChange={(e) => setPhone(e.target.value)}
                      maxLength={20}
                      required
                    />
                  </div>
                  <div className="col-12 col-md-6">
                    <label className="form-label" htmlFor="ob-cpf">
                      CPF (opcional)
                    </label>
                    <input
                      id="ob-cpf"
                      className="form-control"
                      value={cpf}
                      onChange={(e) => setCpf(e.target.value)}
                      maxLength={14}
                    />
                  </div>
                  <div className="col-12">
                    <label className="form-label" htmlFor="ob-reason">
                      Motivo da consulta (opcional)
                    </label>
                    <input
                      id="ob-reason"
                      className="form-control"
                      value={reason}
                      onChange={(e) => setReason(e.target.value)}
                      maxLength={255}
                    />
                  </div>
                </div>

                <div className="form-check mt-3">
                  <input
                    id="ob-consent"
                    type="checkbox"
                    className="form-check-input"
                    checked={consent}
                    onChange={(e) => setConsent(e.target.checked)}
                    required
                  />
                  <label className="form-check-label" htmlFor="ob-consent">
                    Autorizo o tratamento dos meus dados pessoais para fins de
                    agendamento e atendimento, conforme a LGPD.
                  </label>
                </div>

                <div className="d-flex justify-content-between mt-4">
                  <button
                    type="button"
                    className="btn btn-outline-secondary"
                    onClick={() => setStep(2)}
                  >
                    <i className="bi bi-arrow-left me-1" />
                    Voltar
                  </button>
                  <button
                    type="submit"
                    className="btn btn-primary"
                    disabled={submitting}
                  >
                    {submitting && (
                      <span className="spinner-border spinner-border-sm me-2" />
                    )}
                    Confirmar agendamento
                  </button>
                </div>
              </form>
            </div>
          </div>
        )}

        {/* Confirmação */}
        {step === 3 && result && (
          <div className="card border-0 shadow-sm text-center">
            <div className="card-body py-5">
              <i className="bi bi-check-circle-fill display-4 text-success" />
              <h2 className="h4 mt-3">Consulta solicitada!</h2>
              <p className="text-muted">
                Registramos seu pedido. Nossa equipe entrará em contato para
                confirmar.
              </p>
              <ul className="list-unstyled mb-4">
                <li>
                  <strong>Profissional:</strong> {result.dentistName ?? dentist?.fullName}
                </li>
                <li>
                  <strong>Data:</strong> {formatLongDate(date)}
                </li>
                <li>
                  <strong>Horário:</strong>{' '}
                  {formatTimeInZone(result.startAt, timezone)}
                </li>
                {result.reason && (
                  <li>
                    <strong>Motivo:</strong> {result.reason}
                  </li>
                )}
              </ul>
              <button className="btn btn-outline-primary" onClick={reset}>
                <i className="bi bi-plus-lg me-1" />
                Agendar outra consulta
              </button>
            </div>
          </div>
        )}
      </div>
    </>
  );
}
