import type { FC } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { Clock, CheckCircle, XCircle, CheckCheck, UserCheck, Plus, PackageCheck, Sparkles, RotateCcw } from 'lucide-react';
import Layout from '../components/Layout';
import {
  Card,
  Button,
  Input,
  Select,
  TextArea,
  Modal,
  Badge,
  EmptyState,
  MobileCard,
  PageHeader,
  Skeleton,
  toast,
  badgeForAppointmentState,
} from '../components/ui';
import { odooApi, type Appointment, type Patient, type Service, type Doctor } from '../services/odoo';

const stateOptions = [
  { value: '', label: 'Todos los estados' },
  { value: 'pending', label: 'Pendiente' },
  { value: 'confirmed', label: 'Confirmada' },
  { value: 'done', label: 'Completada' },
  { value: 'cancelled', label: 'Cancelada' },
];

const Agenda: FC = () => {
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [patients, setPatients] = useState<Patient[]>([]);
  const [services, setServices] = useState<Service[]>([]);
  const [doctors, setDoctors] = useState<Doctor[]>([]);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [updating, setUpdating] = useState<number | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [date, setDate] = useState<string>(() => new Date().toISOString().split('T')[0]);
  const [stateFilter, setStateFilter] = useState('');
  const [doctorFilter, setDoctorFilter] = useState('');
  const [createOpen, setCreateOpen] = useState(false);
  const [slots, setSlots] = useState<{ time: number; time_str: string }[]>([]);
  const [slotsLoading, setSlotsLoading] = useState(false);

  const [form, setForm] = useState({
    patient_id: '',
    service_id: '',
    doctor_id: '',
    date: new Date().toISOString().split('T')[0],
    time: '',
    notes: '',
  });
  const [patientSearch, setPatientSearch] = useState('');
  const [pkgUpdating, setPkgUpdating] = useState<number | null>(null);
  const [expressOpen, setExpressOpen] = useState(false);
  const [expressSubmitting, setExpressSubmitting] = useState(false);
  const [expressForm, setExpressForm] = useState({
    name: '',
    phone: '',
    notes: '',
    withAppointment: false,
    service_id: '',
    doctor_id: '',
    date: new Date().toISOString().split('T')[0],
    time: '',
  });

  const filteredAppointments = appointments.filter((apt) => {
    if (stateFilter && apt.state !== stateFilter) return false;
    if (doctorFilter && String(apt.doctor_id) !== doctorFilter) return false;
    return true;
  });

  const load = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const params: Record<string, string> = date ? { date } : {};
      const res = await odooApi.getAppointments(params);
      if (res.status === 'success') setAppointments(res.appointments);
    } catch (err) {
      setError('Error al cargar citas');
      toast.error('Error al cargar citas');
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, [date]);

  const loadReferences = useCallback(async () => {
    try {
      const [servicesRes, doctorsRes] = await Promise.all([
        odooApi.getServices(),
        odooApi.getDoctors(),
      ]);
      if (servicesRes.status === 'success') setServices(servicesRes.services);
      if (doctorsRes.status === 'success') setDoctors(doctorsRes.doctors);
    } catch (err) {
      console.error(err);
    }
  }, []);

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

  // Cargar pacientes para el selector (búsqueda server-side)
  useEffect(() => {
    if (!createOpen) return;
    const t = setTimeout(async () => {
      try {
        const res = await odooApi.getPatients({ search: patientSearch, page_size: 50 });
        if (res.status === 'success') setPatients(res.patients);
      } catch (err) {
        console.error(err);
      }
    }, 250);
    return () => clearTimeout(t);
  }, [createOpen, patientSearch]);

  const fetchSlots = useCallback(async (serviceId: string, aptDate: string) => {
    if (!serviceId || !aptDate) {
      setSlots([]);
      return;
    }
    try {
      setSlotsLoading(true);
      const res = await odooApi.getAvailableSlots(aptDate, parseInt(serviceId, 10));
      if (res.status === 'success') setSlots(res.slots);
    } catch {
      toast.error('Error al cargar horarios disponibles');
      setSlots([]);
    } finally {
      setSlotsLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchSlots(form.service_id, form.date);
  }, [form.service_id, form.date, fetchSlots]);

  const handleStatus = async (id: number, action: string) => {
    try {
      setUpdating(id);
      await odooApi.updateAppointmentStatus(id, action);
      toast.success('Estado actualizado');
      await load();
    } catch (err) {
      toast.error('Error al actualizar estado');
      console.error(err);
    } finally {
      setUpdating(null);
    }
  };

  const handlePackageFinished = async (id: number, finished: boolean) => {
    try {
      setPkgUpdating(id);
      await odooApi.packageFinished(id, finished);
      toast.success(finished ? 'Paquete marcado como terminado' : 'Marca de paquete revertida');
      await load();
    } catch (err) {
      toast.error('Error al actualizar paquete');
      console.error(err);
    } finally {
      setPkgUpdating(null);
    }
  };

  const parseTimeToFloat = (t: string): number | undefined => {
    if (!t) return undefined;
    const [h, m] = t.split(':').map((x) => parseInt(x, 10));
    if (Number.isNaN(h)) return undefined;
    return h + (Number.isNaN(m) ? 0 : m / 60);
  };

  const resetExpressForm = () =>
    setExpressForm({
      name: '', phone: '', notes: '', withAppointment: false,
      service_id: '', doctor_id: '', date: new Date().toISOString().split('T')[0], time: '',
    });

  const submitExpress = async () => {
    if (!expressForm.name.trim() || !expressForm.phone.trim()) {
      toast.error('Nombre y teléfono son obligatorios');
      return;
    }
    if (expressForm.withAppointment && (!expressForm.service_id || !expressForm.date || !expressForm.time)) {
      toast.error('Para la cita de valoración selecciona servicio, fecha y hora');
      return;
    }
    try {
      setExpressSubmitting(true);
      const patientPayload: Partial<Patient> & { notes?: string } = {
        name: expressForm.name.trim(),
        phone: expressForm.phone.trim(),
        source: 'walkin',
        notes: expressForm.notes || undefined,
      };
      const res = await odooApi.createPatient(patientPayload);
      const newId = res.patient?.id;
      if (expressForm.withAppointment && newId) {
        await odooApi.createAppointment({
          patient_id: newId,
          service_id: parseInt(expressForm.service_id, 10),
          doctor_id: expressForm.doctor_id ? parseInt(expressForm.doctor_id, 10) : undefined,
          date: expressForm.date,
          time: parseTimeToFloat(expressForm.time) as unknown as string,
          notes: 'Valoración express',
          state: 'confirmed',
        });
      }
      toast.success(expressForm.withAppointment ? 'Prospecto y cita de valoración creados' : 'Prospecto creado');
      setExpressOpen(false);
      resetExpressForm();
      await load();
    } catch (err) {
      toast.error('Error en valoración express');
      console.error(err);
    } finally {
      setExpressSubmitting(false);
    }
  };

  const createAppointment = async () => {
    if (!form.patient_id || !form.service_id || !form.date || !form.time) {
      toast.error('Completa los campos obligatorios');
      return;
    }
    try {
      setSubmitting(true);
      await odooApi.createAppointment({
        patient_id: parseInt(form.patient_id, 10),
        service_id: parseInt(form.service_id, 10),
        doctor_id: form.doctor_id ? parseInt(form.doctor_id, 10) : undefined,
        date: form.date,
        time: form.time,
        notes: form.notes,
      });
      toast.success('Cita creada');
      setCreateOpen(false);
      setForm({
        patient_id: '',
        service_id: '',
        doctor_id: '',
        date: new Date().toISOString().split('T')[0],
        time: '',
        notes: '',
      });
      await load();
    } catch (err) {
      toast.error('Error al crear cita');
      console.error(err);
    } finally {
      setSubmitting(false);
    }
  };

  const doctorOptions = [
    { value: '', label: 'Todos los médicos' },
    ...doctors.map((d) => ({ value: String(d.id), label: d.name })),
  ];

  const patientOptions = [
    { value: '', label: 'Seleccionar paciente...' },
    ...patients.map((p) => ({ value: String(p.id), label: `${p.name} (${p.phone})` })),
  ];

  const serviceOptions = [
    { value: '', label: 'Seleccionar servicio...' },
    ...services.map((s) => ({ value: String(s.id), label: `${s.name} — $${s.price}` })),
  ];

  const slotOptions = slots.length
    ? [
        { value: '', label: 'Seleccionar hora...' },
        ...slots.map((s) => ({ value: s.time_str, label: s.time_str })),
      ]
    : [
        { value: '', label: 'Selecciona servicio y fecha primero' },
      ];

  const TableHeader = () => (
    <thead className="bg-[#FEF3C7]">
      <tr>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase">Hora</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase">Paciente</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase hidden sm:table-cell">Servicio</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase hidden md:table-cell">Doctor</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase">Estado</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase hidden sm:table-cell">Pago</th>
        <th className="text-left p-3 text-xs font-medium text-[#7A5C44] uppercase">Acciones</th>
      </tr>
    </thead>
  );

  const ActionButtons = ({ apt }: { apt: Appointment }) => (
    <div className="flex items-center gap-1">
      {apt.state !== 'confirmed' && apt.state !== 'done' && apt.state !== 'cancelled' && (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => handleStatus(apt.id, 'confirm')}
          disabled={updating === apt.id}
          title="Confirmar"
        >
          <CheckCircle size={16} className="text-#3E2C1C" />
        </Button>
      )}
      {apt.state === 'confirmed' && (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => handleStatus(apt.id, 'arrive')}
          disabled={updating === apt.id}
          title="Llegada"
        >
          <UserCheck size={16} className="text-blue-600" />
        </Button>
      )}
      {apt.state !== 'done' && apt.state !== 'cancelled' && (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => handleStatus(apt.id, 'done')}
          disabled={updating === apt.id}
          title="Completar"
        >
          <CheckCheck size={16} className="text-blue-600" />
        </Button>
      )}
      {apt.service_category === 'paquete' && apt.state !== 'cancelled' && (
        apt.package_finished ? (
          <Button
            variant="ghost"
            size="sm"
            onClick={() => handlePackageFinished(apt.id, false)}
            disabled={pkgUpdating === apt.id}
            title="Paquete terminado — click para revertir"
          >
            <RotateCcw size={16} className="text-amber-600" />
          </Button>
        ) : (
          <Button
            variant="ghost"
            size="sm"
            onClick={() => handlePackageFinished(apt.id, true)}
            disabled={pkgUpdating === apt.id}
            title="Marcar paquete terminado"
          >
            <PackageCheck size={16} className="text-violet-600" />
          </Button>
        )
      )}
      {apt.state !== 'cancelled' && (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => handleStatus(apt.id, 'cancel')}
          disabled={updating === apt.id}
          title="Cancelar"
        >
          <XCircle size={16} className="text-rose-600" />
        </Button>
      )}
    </div>
  );

  return (
    <Layout title="Agenda" subtitle="Gestión de citas">
      <PageHeader title="Agenda" subtitle="Filtra por fecha, estado o médico">
        <Button variant="outline" onClick={() => setExpressOpen(true)}>
          <Sparkles size={16} className="mr-2" />
          Valoración express
        </Button>
        <Button onClick={() => setCreateOpen(true)}>
          <Plus size={16} className="mr-2" />
          Nueva cita
        </Button>
      </PageHeader>

      <Card>
        <Card.Body>
          <div className="flex flex-col sm:flex-row sm:items-end gap-3 sm:gap-4 mb-4 sm:mb-6">
            <Input
              label="Fecha"
              type="date"
              value={date}
              onChange={(e) => setDate(e.target.value)}
              className="sm:max-w-[180px]"
            />
            <Select
              label="Estado"
              options={stateOptions}
              value={stateFilter}
              onChange={(e) => setStateFilter(e.target.value)}
              className="sm:max-w-[180px]"
            />
            <Select
              label="Médico"
              options={doctorOptions}
              value={doctorFilter}
              onChange={(e) => setDoctorFilter(e.target.value)}
              className="sm:max-w-[220px]"
            />
          </div>

          {error && <p className="text-rose-600 text-sm mb-4">{error}</p>}

          {loading ? (
            <Skeleton count={6} className="h-12 w-full" />
          ) : filteredAppointments.length === 0 ? (
            <EmptyState
              title="Sin citas"
              subtitle="No hay citas para los filtros seleccionados."
              actionLabel="Nueva cita"
              onAction={() => setCreateOpen(true)}
            />
          ) : (
            <>
              {/* Desktop table */}
              <div className="hidden sm:block overflow-x-auto">
                <table className="w-full">
                  <TableHeader />
                  <tbody className="divide-y">
                    {filteredAppointments.map((apt) => (
                      <tr key={apt.id} className="hover:bg-[#FEF3C7]">
                        <td className="p-3 text-sm text-homenest-bark">
                          <Clock size={14} className="inline mr-1 text-[#A87B5D]" />
                          {apt.time}
                        </td>
                        <td className="p-3 text-sm font-medium text-homenest-bark">{apt.patient}</td>
                        <td className="p-3 text-sm text-[#7A5C44] hidden sm:table-cell">{apt.service}</td>
                        <td className="p-3 text-sm text-[#7A5C44] hidden md:table-cell">{apt.doctor || '-'}</td>
                        <td className="p-3">
                          <Badge variant={badgeForAppointmentState(apt.state)}>{apt.state}</Badge>
                        </td>
                        <td className="p-3 text-sm text-[#7A5C44] hidden sm:table-cell">{apt.payment_state}</td>
                        <td className="p-3">
                          <ActionButtons apt={apt} />
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              {/* Mobile cards */}
              <div className="sm:hidden space-y-3">
                {filteredAppointments.map((apt) => (
                  <MobileCard
                    key={apt.id}
                    title={apt.patient}
                    subtitle={apt.service}
                    rows={[
                      { label: 'Hora', value: apt.time },
                      { label: 'Doctor', value: apt.doctor || '-' },
                      { label: 'Estado', value: <Badge variant={badgeForAppointmentState(apt.state)}>{apt.state}</Badge> },
                      { label: 'Pago', value: apt.payment_state },
                    ]}
                    actions={<ActionButtons apt={apt} />}
                  />
                ))}
              </div>
            </>
          )}
        </Card.Body>
      </Card>

      <Modal
        isOpen={createOpen}
        onClose={() => setCreateOpen(false)}
        title="Nueva cita"
        maxWidth="lg"
        footer={
          <>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>Cancelar</Button>
            <Button onClick={createAppointment} loading={submitting}>Guardar cita</Button>
          </>
        }
      >
        <div className="space-y-4">
          <Input
            label="Buscar paciente"
            placeholder="Escribe nombre o teléfono..."
            value={patientSearch}
            onChange={(e) => setPatientSearch(e.target.value)}
          />
          <Select
            label="Paciente *"
            options={patientOptions}
            value={form.patient_id}
            onChange={(e) => setForm({ ...form, patient_id: e.target.value })}
          />
          <Select
            label="Servicio *"
            options={serviceOptions}
            value={form.service_id}
            onChange={(e) => setForm({ ...form, service_id: e.target.value })}
          />
          <Select
            label="Médico"
            options={[{ value: '', label: 'Sin preferencia' }, ...doctors.map((d) => ({ value: String(d.id), label: d.name }))]}
            value={form.doctor_id}
            onChange={(e) => setForm({ ...form, doctor_id: e.target.value })}
          />
          <div className="grid grid-cols-2 gap-4">
            <Input
              label="Fecha *"
              type="date"
              value={form.date}
              onChange={(e) => setForm({ ...form, date: e.target.value })}
            />
            <Select
              label="Hora *"
              options={slotOptions}
              value={form.time}
              onChange={(e) => setForm({ ...form, time: e.target.value })}
              disabled={slotsLoading || !form.service_id || !form.date}
            />
          </div>
          {slotsLoading && <p className="text-xs text-[#7A5C44]">Cargando horarios disponibles...</p>}
          <TextArea
            label="Notas"
            value={form.notes}
            onChange={(e) => setForm({ ...form, notes: e.target.value })}
          />
        </div>
      </Modal>

      <Modal
        isOpen={expressOpen}
        onClose={() => setExpressOpen(false)}
        title="Valoración express"
        maxWidth="md"
        footer={
          <>
            <Button variant="outline" onClick={() => setExpressOpen(false)}>Cancelar</Button>
            <Button onClick={submitExpress} loading={expressSubmitting}>Guardar</Button>
          </>
        }
      >
        <div className="space-y-4">
          <p className="text-sm text-[#7A5C44]">
            Captura rápida de prospecto. Opcionalmente agenda su cita de valoración en el mismo paso.
          </p>
          <Input
            label="Nombre *"
            placeholder="Nombre del prospecto"
            value={expressForm.name}
            onChange={(e) => setExpressForm({ ...expressForm, name: e.target.value })}
          />
          <Input
            label="Teléfono *"
            placeholder="+52 ..."
            value={expressForm.phone}
            onChange={(e) => setExpressForm({ ...expressForm, phone: e.target.value })}
          />
          <TextArea
            label="Notas"
            placeholder="Motivo de consulta, zona a tratar, etc."
            value={expressForm.notes}
            onChange={(e) => setExpressForm({ ...expressForm, notes: e.target.value })}
          />
          <label className="inline-flex items-center gap-2 text-sm text-homenest-bark cursor-pointer">
            <input
              type="checkbox"
              checked={expressForm.withAppointment}
              onChange={(e) => setExpressForm({ ...expressForm, withAppointment: e.target.checked })}
              className="rounded border-[#E9D5B7]"
            />
            Crear cita de valoración ahora
          </label>
          {expressForm.withAppointment && (
            <div className="space-y-4 rounded-xl border border-[#F5EBD8] p-4 bg-[#FEF3C7]">
              <Select
                label="Servicio *"
                options={serviceOptions}
                value={expressForm.service_id}
                onChange={(e) => setExpressForm({ ...expressForm, service_id: e.target.value })}
              />
              <Select
                label="Médico"
                options={[{ value: '', label: 'Sin preferencia' }, ...doctors.map((d) => ({ value: String(d.id), label: d.name }))]}
                value={expressForm.doctor_id}
                onChange={(e) => setExpressForm({ ...expressForm, doctor_id: e.target.value })}
              />
              <div className="grid grid-cols-2 gap-4">
                <Input
                  label="Fecha *"
                  type="date"
                  value={expressForm.date}
                  onChange={(e) => setExpressForm({ ...expressForm, date: e.target.value })}
                />
                <Input
                  label="Hora *"
                  type="time"
                  value={expressForm.time}
                  onChange={(e) => setExpressForm({ ...expressForm, time: e.target.value })}
                />
              </div>
            </div>
          )}
        </div>
      </Modal>
    </Layout>
  );
};

export default Agenda;
