'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import Swal from 'sweetalert2';
import { RequireRole } from '@/lib/auth-context';
import {
  EmptyState,
  ErrorAlert,
  Loading,
  PageHeader,
} from '@/components/app/ui';
import AppointmentModal from '@/components/app/agenda/AppointmentModal';
import { extractApiError } from '@/lib/api-client';
import {
  formatDateInZone,
  formatLongDate,
  formatTimeInZone,
  todayInZone,
} from '@/lib/datetime';
import {
  cancelAppointment,
  getClinicSettings,
  getMyAppointments,
} from '@/lib/services/appointments';
import {
  ACTIVE_APPOINTMENT_STATUSES,
  APPOINTMENT_STATUS_BADGES,
  APPOINTMENT_STATUS_LABELS,
  type Appointment,
} from '@/lib/types';

const FALLBACK_TIMEZONE = 'America/Sao_Paulo';

export default function PortalConsultasPage() {
  return (
    <RequireRole roles={['patient']}>
      <ConsultasContent />
    </RequireRole>
  );
}

function ConsultasContent() {
  const [timezone, setTimezone] = useState(FALLBACK_TIMEZONE);
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [modalOpen, setModalOpen] = useState(false);
  const [modalAppointment, setModalAppointment] =
    useState<Appointment | null>(null);

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        const settings = await getClinicSettings();
        if (active && typeof settings.timezone === 'string') {
          setTimezone(settings.timezone);
        }
      } catch {
        /* mantém o padrão */
      }
    })();
    return () => {
      active = false;
    };
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const page = await getMyAppointments();
      setAppointments(page.data);
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const { upcoming, past } = useMemo(() => {
    const now = Date.now();
    const isActive = (a: Appointment) =>
      ACTIVE_APPOINTMENT_STATUSES.includes(a.status);
    const ascending = [...appointments].sort(
      (a, b) => new Date(a.startAt).getTime() - new Date(b.startAt).getTime(),
    );
    return {
      upcoming: ascending.filter(
        (a) => isActive(a) && new Date(a.startAt).getTime() >= now,
      ),
      past: ascending
        .filter((a) => !(isActive(a) && new Date(a.startAt).getTime() >= now))
        .reverse(),
    };
  }, [appointments]);

  async function handleCancel(appointment: Appointment) {
    const { value, isConfirmed } = await Swal.fire<string>({
      icon: 'warning',
      title: 'Cancelar consulta?',
      input: 'text',
      inputLabel: 'Motivo (opcional)',
      inputPlaceholder: 'Ex.: não poderei comparecer',
      showCancelButton: true,
      confirmButtonText: 'Cancelar consulta',
      cancelButtonText: 'Voltar',
      confirmButtonColor: '#dc3545',
    });
    if (!isConfirmed) return;
    try {
      await cancelAppointment(appointment.id, value || undefined);
      await Swal.fire({
        icon: 'success',
        title: 'Consulta cancelada',
        timer: 1400,
        showConfirmButton: false,
      });
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  function AppointmentsList({ items }: { items: Appointment[] }) {
    if (items.length === 0) return null;
    return (
      <div className="row g-3">
        {items.map((appointment) => {
          const isActive = ACTIVE_APPOINTMENT_STATUSES.includes(
            appointment.status,
          );
          return (
            <div className="col-12 col-lg-6" key={appointment.id}>
              <div className="card border-0 shadow-sm h-100">
                <div className="card-body">
                  <div className="d-flex justify-content-between align-items-start mb-2">
                    <div>
                      <div className="fw-semibold">
                        {formatDateInZone(appointment.startAt, timezone)} ·{' '}
                        {formatTimeInZone(appointment.startAt, timezone)}
                      </div>
                      <small className="text-muted">
                        {appointment.dentist?.fullName ?? 'Profissional'}
                      </small>
                    </div>
                    <span
                      className={`badge ${APPOINTMENT_STATUS_BADGES[appointment.status]}`}
                    >
                      {APPOINTMENT_STATUS_LABELS[appointment.status]}
                    </span>
                  </div>
                  {appointment.reason && (
                    <p className="mb-2 small">
                      <i className="bi bi-clipboard2-pulse me-1 text-muted" />
                      {appointment.reason}
                    </p>
                  )}
                  {isActive && (
                    <div className="d-flex gap-2">
                      <button
                        className="btn btn-sm btn-outline-primary"
                        onClick={() => {
                          setModalAppointment(appointment);
                          setModalOpen(true);
                        }}
                      >
                        <i className="bi bi-arrow-repeat me-1" />
                        Remarcar
                      </button>
                      <button
                        className="btn btn-sm btn-outline-danger"
                        onClick={() => handleCancel(appointment)}
                      >
                        <i className="bi bi-x-lg me-1" />
                        Cancelar
                      </button>
                    </div>
                  )}
                </div>
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  return (
    <>
      <PageHeader
        title="Minhas consultas"
        subtitle={`Horários no fuso da clínica (${timezone})`}
        action={
          <a href="/agendar" className="btn btn-primary">
            <i className="bi bi-plus-lg me-1" />
            Agendar consulta
          </a>
        }
      />

      {error ? (
        <ErrorAlert message={error} onRetry={load} />
      ) : loading ? (
        <Loading label="Carregando suas consultas…" />
      ) : appointments.length === 0 ? (
        <EmptyState
          icon="bi-calendar3"
          title="Você ainda não tem consultas"
          description="Agende sua primeira consulta online."
          action={
            <a href="/agendar" className="btn btn-primary mt-2">
              Agendar consulta
            </a>
          }
        />
      ) : (
        <>
          <h2 className="h6 text-muted text-uppercase mb-3">Próximas</h2>
          {upcoming.length === 0 ? (
            <p className="text-muted">Nenhuma consulta futura agendada.</p>
          ) : (
            <AppointmentsList items={upcoming} />
          )}

          {past.length > 0 && (
            <>
              <h2 className="h6 text-muted text-uppercase mt-4 mb-3">
                Histórico
              </h2>
              <AppointmentsList items={past} />
            </>
          )}
        </>
      )}

      <AppointmentModal
        open={modalOpen}
        mode="reschedule"
        appointment={modalAppointment}
        timezone={timezone}
        defaultDate={todayInZone(timezone)}
        onClose={() => setModalOpen(false)}
        onSaved={load}
      />
    </>
  );
}
