/**
 * ChatbotContainer — asistente conversacional con datos reales de Supabase.
 *
 * Arquitectura lista para IA real: la función processMessage() actualmente
 * usa un motor de reglas. Para conectar un LLM, sustituye su cuerpo por
 * una llamada a la API (Claude, GPT, etc.) pasando los datos de reservas
 * como contexto del sistema.
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import { MessageCircle, X, Send, Home, RefreshCw } from 'lucide-react';
import { supabase } from '../lib/supabase';
import type { Reservation, Property } from '../types';
import { format, parseISO, isAfter, isBefore, differenceInDays } from 'date-fns';
import { es } from 'date-fns/locale/es';

// ─── Types ────────────────────────────────────────────────────────────────────

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
}

// ─── Helpers ─────────────────────────────────────────────────────────────────

function fmtDate(d: string) {
  return format(parseISO(d), "d MMM yyyy", { locale: es });
}

function fmtShort(d: string) {
  return format(parseISO(d), "d MMM", { locale: es });
}

function propertyLabel(p: Property) {
  return p === 'los_dragos' ? 'Los Dragos' : 'La Esquinita';
}

function nightsBetween(start: string, end: string) {
  return differenceInDays(parseISO(end), parseISO(start));
}

// ─── Response engine ──────────────────────────────────────────────────────────

function guestDetail(r: Reservation): string {
  const nights = nightsBetween(r.start_date, r.end_date);
  const pax = r.adults_count + r.children_count;
  const lines: string[] = [
    `👤 **${r.client_name}**`,
    `📅 ${fmtDate(r.start_date)} → ${fmtDate(r.end_date)} (${nights} noche${nights !== 1 ? 's' : ''})`,
    `👥 ${pax} persona${pax !== 1 ? 's' : ''} (${r.adults_count} adultos, ${r.children_count} niños)`,
    `🏷️ Origen: ${r.origin}`,
  ];
  if (r.government_registration) {
    lines.push(`🏛️ Reg. gubernamental: \`${r.government_registration}\``);
  } else {
    lines.push(`⚠️ Sin registro gubernamental`);
  }
  if (r.invoice_number) lines.push(`🧾 Factura: ${r.invoice_number}`);
  if (r.has_cleaning) lines.push(`🧹 Servicio de limpieza incluido`);
  if (r.has_pool_heating) lines.push(`♨️ Calefacción de piscina incluida`);
  if (r.has_flies_products) lines.push(`🦟 Productos anti-mosquitos incluidos`);
  if (r.is_event) {
    lines.push(`🎉 Evento: ${r.event_type ?? ''}${r.event_type_other ? ` (${r.event_type_other})` : ''}`);
    if (r.attendees_count) lines.push(`   Asistentes: ${r.attendees_count}`);
  }
  if (r.pricing_snapshot) {
    const p = r.pricing_snapshot;
    lines.push(`💶 Total: ${p.total.toLocaleString('es-ES', { style: 'currency', currency: 'EUR' })}`);
  }
  if (r.observations) lines.push(`📝 Notas: ${r.observations}`);
  return lines.join('\n');
}

function statsInfo(reservations: Reservation[], property: Property): string {
  const now = new Date();
  const label = propertyLabel(property);
  const total = reservations.length;
  const active = reservations.filter(r =>
    !isAfter(parseISO(r.start_date), now) && !isBefore(parseISO(r.end_date), now)
  );
  const upcoming = reservations.filter(r => isAfter(parseISO(r.start_date), now));
  const past = reservations.filter(r => isBefore(parseISO(r.end_date), now));
  const teneriffa = reservations.filter(r => r.origin === 'Teneriffa2000');
  const natur = reservations.filter(r => r.origin === 'Naturcalabacera');
  const withReg = reservations.filter(r => r.government_registration);
  const withoutReg = reservations.filter(r => !r.government_registration);
  const totalNights = reservations.reduce((sum, r) => sum + nightsBetween(r.start_date, r.end_date), 0);

  const lines = [
    `📊 **Resumen — ${label}**\n`,
    `• Total reservas: **${total}**`,
    `• Activas ahora: ${active.length}`,
    `• Próximas: ${upcoming.length}`,
    `• Pasadas: ${past.length}`,
    `• Noches totales reservadas: ${totalNights}`,
    ``,
    `📋 **Por origen:**`,
    `• Teneriffa2000: ${teneriffa.length}`,
    `• Naturcalabacera: ${natur.length}`,
    ``,
    `🏛️ **Registros gubernamentales:**`,
    `• Con registro: ${withReg.length}`,
    `• Sin registro: ${withoutReg.length}${withoutReg.length > 0 ? ' ⚠️' : ' ✅'}`,
  ];
  return lines.join('\n');
}

function contractsInfo(reservations: Reservation[]): string {
  const now = new Date();
  const withReg = reservations.filter(r => r.government_registration);
  const pendingReg = reservations.filter(
    r => !r.government_registration && !isBefore(parseISO(r.end_date), now)
  );

  const lines: string[] = ['🏛️ **Registros y contratos**\n'];

  if (withReg.length > 0) {
    lines.push(`✅ **Con registro (${withReg.length}):**`);
    withReg.forEach(r => {
      lines.push(`• ${r.client_name} — \`${r.government_registration}\``);
      if (r.invoice_number) lines.push(`  Factura: ${r.invoice_number}`);
      lines.push(`  ${fmtShort(r.start_date)} → ${fmtShort(r.end_date)}`);
    });
  }

  if (pendingReg.length > 0) {
    lines.push(`\n⚠️ **Sin registro (activas/futuras) — ${pendingReg.length}:**`);
    pendingReg.forEach(r => {
      lines.push(`• ${r.client_name} (${fmtShort(r.start_date)} → ${fmtShort(r.end_date)})`);
    });
  }

  if (withReg.length === 0 && pendingReg.length === 0) {
    lines.push('No hay reservas con información de contratos disponible.');
  }

  return lines.join('\n');
}

function upcomingInfo(reservations: Reservation[]): string {
  const now = new Date();
  const upcoming = reservations
    .filter(r => isAfter(parseISO(r.start_date), now))
    .sort((a, b) => a.start_date.localeCompare(b.start_date))
    .slice(0, 6);

  if (upcoming.length === 0) return 'No hay reservas futuras registradas.';

  const lines = [`📅 **Próximas reservas (${upcoming.length}):**\n`];
  upcoming.forEach(r => {
    const daysTo = differenceInDays(parseISO(r.start_date), now);
    const nights = nightsBetween(r.start_date, r.end_date);
    lines.push(
      `**${r.client_name}** — en ${daysTo} día${daysTo !== 1 ? 's' : ''}\n` +
      `  ${fmtShort(r.start_date)} → ${fmtShort(r.end_date)} · ${nights} noches · ${r.adults_count + r.children_count} pax\n` +
      (r.government_registration ? `  ✅ Reg: \`${r.government_registration}\`` : `  ⚠️ Sin registro`)
    );
  });
  return lines.join('\n');
}

function availabilityInfo(reservations: Reservation[]): string {
  const now = new Date();
  const future = reservations
    .filter(r => !isBefore(parseISO(r.end_date), now))
    .sort((a, b) => a.start_date.localeCompare(b.start_date));

  if (future.length === 0) {
    return '✅ No hay reservas futuras. La propiedad está completamente disponible.';
  }

  const lines = ['🗓️ **Disponibilidad próxima:**\n'];

  // Gap before first reservation
  const firstStart = parseISO(future[0].start_date);
  const daysToFirst = differenceInDays(firstStart, now);
  if (daysToFirst > 0) {
    lines.push(`✅ Libre ahora → ${fmtShort(future[0].start_date)} (${daysToFirst} días)`);
  }

  // Gaps between reservations
  for (let i = 0; i < future.length; i++) {
    lines.push(`🔴 Ocupado: ${fmtShort(future[i].start_date)} → ${fmtShort(future[i].end_date)} (${future[i].client_name})`);
    if (i < future.length - 1) {
      const gapStart = parseISO(future[i].end_date);
      const gapEnd = parseISO(future[i + 1].start_date);
      const gapDays = differenceInDays(gapEnd, gapStart);
      if (gapDays > 0) {
        lines.push(`✅ Libre: ${fmtShort(future[i].end_date)} → ${fmtShort(future[i + 1].start_date)} (${gapDays} días)`);
      }
    }
  }

  return lines.join('\n');
}

function allReservationsInfo(reservations: Reservation[]): string {
  if (reservations.length === 0) return 'No hay reservas registradas.';

  const sorted = [...reservations].sort((a, b) => a.start_date.localeCompare(b.start_date));
  const now = new Date();
  const lines = [`📋 **Todas las reservas (${sorted.length}):**\n`];

  sorted.forEach(r => {
    const isPast = isBefore(parseISO(r.end_date), now);
    const isActive = !isAfter(parseISO(r.start_date), now) && !isBefore(parseISO(r.end_date), now);
    const icon = isPast ? '⬜' : isActive ? '🟢' : '🔵';
    lines.push(
      `${icon} **${r.client_name}** — ${fmtShort(r.start_date)} → ${fmtShort(r.end_date)}` +
      (r.government_registration ? ` ✅` : ` ⚠️`)
    );
  });

  return lines.join('\n');
}

function processMessage(input: string, reservations: Reservation[], property: Property): string {
  const lower = input.toLowerCase().trim();
  const now = new Date();
  const label = propertyLabel(property);

  // Greeting
  if (/^(hola|buenos|buenas|hey|hi|ey|qué tal|que tal|buen)/.test(lower)) {
    const total = reservations.length;
    const upcoming = reservations.filter(r => isAfter(parseISO(r.start_date), now)).length;
    const active = reservations.filter(r =>
      !isAfter(parseISO(r.start_date), now) && !isBefore(parseISO(r.end_date), now)
    ).length;
    return [
      `¡Hola! Soy tu asistente para **${label}** 🏡`,
      ``,
      `Estado actual:`,
      `• ${active > 0 ? `🟢 ${active} reserva${active !== 1 ? 's' : ''} activa${active !== 1 ? 's' : ''} ahora mismo` : '⬜ Sin reservas activas hoy'}`,
      `• 🔵 ${upcoming} próxima${upcoming !== 1 ? 's' : ''}`,
      `• 📋 ${total} reserva${total !== 1 ? 's' : ''} en total`,
      ``,
      `¿Qué necesitas saber?`,
    ].join('\n');
  }

  // Stats / summary
  if (/estadist|resumen|total|cuántas|cuantas|dato|cifra|número|numeros|summary/.test(lower)) {
    return statsInfo(reservations, property);
  }

  // Contracts / government registration
  if (/contrat|registro|viajero|govern|código|codigos|rvtca|factura|invoice|número de registro/.test(lower)) {
    return contractsInfo(reservations);
  }

  // Upcoming
  if (/próxim|siguiente|futuras|upcoming|pronto|esta semana|este mes|entran|llegan/.test(lower)) {
    return upcomingInfo(reservations);
  }

  // Availability
  if (/disponib|libre|ocup|vac|hueco|cuando|free|gap|abierto/.test(lower)) {
    return availabilityInfo(reservations);
  }

  // List all
  if (/lista|todas|todos|ver todo|todas las|show all|all reserv/.test(lower)) {
    return allReservationsInfo(reservations);
  }

  // Search by guest name — scan all words in input against client names
  const words = lower.split(/\s+/).filter(w => w.length > 2);
  for (const word of words) {
    const found = reservations.find(r =>
      r.client_name.toLowerCase().includes(word)
    );
    if (found) return guestDetail(found);
  }

  // Help / default
  return [
    `Puedo ayudarte con información de **${label}**. Pregúntame sobre:`,
    ``,
    `• 📋 **Reservas** — "lista todas", "reservas de mayo"`,
    `• 📅 **Próximas** — "próximas reservas"`,
    `• 🗓️ **Disponibilidad** — "¿cuándo está libre?"`,
    `• 🏛️ **Contratos** — "registros gubernamentales", "contratos"`,
    `• 👤 **Huésped** — escribe el nombre del cliente`,
    `• 📊 **Estadísticas** — "dame un resumen"`,
  ].join('\n');
}

// ─── Quick-reply suggestions ──────────────────────────────────────────────────

const QUICK_REPLIES = [
  { label: 'Próximas reservas', text: 'próximas reservas' },
  { label: 'Disponibilidad', text: '¿cuándo está libre?' },
  { label: 'Contratos y registros', text: 'registros gubernamentales' },
  { label: 'Resumen estadístico', text: 'dame un resumen' },
  { label: 'Todas las reservas', text: 'lista todas las reservas' },
];

// ─── Message renderer (markdown-lite) ────────────────────────────────────────

function RenderMessage({ content }: { content: string }) {
  const lines = content.split('\n');
  return (
    <div className="space-y-0.5">
      {lines.map((line, i) => {
        // Bold: **text**
        const parts = line.split(/(\*\*[^*]+\*\*)/g).map((part, j) => {
          if (part.startsWith('**') && part.endsWith('**')) {
            return <strong key={j}>{part.slice(2, -2)}</strong>;
          }
          // Inline code: `text`
          return part.split(/(`[^`]+`)/g).map((seg, k) => {
            if (seg.startsWith('`') && seg.endsWith('`')) {
              return (
                <code key={k} className="bg-white/10 px-1 py-0.5 rounded text-xs font-mono">
                  {seg.slice(1, -1)}
                </code>
              );
            }
            return seg;
          });
        });
        if (line === '') return <div key={i} className="h-1.5" />;
        return <p key={i} className="leading-snug">{parts}</p>;
      })}
    </div>
  );
}

// ─── Main component ───────────────────────────────────────────────────────────

export function ChatbotContainer() {
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [selectedProperty, setSelectedProperty] = useState<Property>('los_dragos');
  const [reservationsMap, setReservationsMap] = useState<Record<Property, Reservation[]>>({
    los_dragos: [],
    la_esquinita: [],
  });
  const [loadingData, setLoadingData] = useState(false);
  const [isTyping, setIsTyping] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Fetch all reservations for both properties
  const fetchAll = useCallback(async () => {
    setLoadingData(true);
    try {
      const { data } = await supabase
        .from('reservations')
        .select('*')
        .order('start_date', { ascending: true });
      if (data) {
        setReservationsMap({
          los_dragos: data.filter((r: Reservation) => r.property === 'los_dragos'),
          la_esquinita: data.filter((r: Reservation) => r.property === 'la_esquinita'),
        });
      }
    } finally {
      setLoadingData(false);
    }
  }, []);

  useEffect(() => {
    if (isOpen && messages.length === 0) {
      fetchAll();
      // Initial greeting
      const greeting: Message = {
        id: crypto.randomUUID(),
        role: 'assistant',
        content: `¡Hola! 👋 Soy tu asistente de reservas.\n\nSelecciona una propiedad arriba y pregúntame lo que necesites: disponibilidad, contratos, huéspedes, estadísticas…`,
        timestamp: new Date(),
      };
      setMessages([greeting]);
    }
  }, [isOpen, messages.length, fetchAll]);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages, isTyping]);

  const handleSend = useCallback(async (text?: string) => {
    const userText = (text ?? input).trim();
    if (!userText) return;

    const userMsg: Message = {
      id: crypto.randomUUID(),
      role: 'user',
      content: userText,
      timestamp: new Date(),
    };
    setMessages(prev => [...prev, userMsg]);
    setInput('');
    setIsTyping(true);

    // Simulate processing delay for UX
    await new Promise(resolve => setTimeout(resolve, 400));

    const reservations = reservationsMap[selectedProperty];
    const response = processMessage(userText, reservations, selectedProperty);

    const botMsg: Message = {
      id: crypto.randomUUID(),
      role: 'assistant',
      content: response,
      timestamp: new Date(),
    };
    setIsTyping(false);
    setMessages(prev => [...prev, botMsg]);
  }, [input, reservationsMap, selectedProperty]);

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };

  const handlePropertySwitch = (p: Property) => {
    setSelectedProperty(p);
    const switchMsg: Message = {
      id: crypto.randomUUID(),
      role: 'assistant',
      content: `Cambiado a **${propertyLabel(p)}**. ¿Qué necesitas saber sobre esta propiedad?`,
      timestamp: new Date(),
    };
    setMessages(prev => [...prev, switchMsg]);
  };

  const isDragos = selectedProperty === 'los_dragos';
  const accentGradient = isDragos
    ? 'from-emerald-600 to-teal-600'
    : 'from-amber-600 to-orange-600';
  const accentBorder = isDragos ? 'border-emerald-500/30' : 'border-amber-500/30';
  const accentShadow = isDragos ? 'shadow-emerald-500/20' : 'shadow-amber-500/20';
  const accentBg = isDragos ? 'bg-emerald-600/20' : 'bg-amber-600/20';
  const accentText = isDragos ? 'text-emerald-300' : 'text-amber-300';
  const activePropBg = isDragos
    ? 'bg-gradient-to-r from-emerald-600 to-teal-600 text-white shadow-lg shadow-emerald-500/30'
    : 'bg-gradient-to-r from-amber-600 to-orange-600 text-white shadow-lg shadow-amber-500/30';

  return (
    <>
      {/* Floating button */}
      <button
        onClick={() => setIsOpen(o => !o)}
        className={`fixed bottom-20 right-4 md:bottom-6 md:right-6 z-50 w-14 h-14 bg-gradient-to-br ${accentGradient} rounded-full shadow-xl ${accentShadow} flex items-center justify-center text-white transition-all duration-300 hover:scale-110 border border-white/10`}
        aria-label="Abrir asistente"
      >
        {isOpen ? <X className="w-6 h-6" /> : <MessageCircle className="w-6 h-6" />}
      </button>

      {/* Chat panel */}
      {isOpen && (
        <div
          className={`fixed bottom-36 right-4 md:bottom-24 md:right-6 z-50 w-[calc(100vw-2rem)] md:w-96 h-[520px] md:h-[580px] bg-slate-900 rounded-3xl shadow-2xl ${accentShadow} border ${accentBorder} flex flex-col overflow-hidden transition-all duration-300`}
        >
          {/* Header */}
          <div className={`bg-gradient-to-r ${accentGradient} px-5 py-4 flex items-center justify-between flex-shrink-0`}>
            <div className="flex items-center gap-3">
              <div className="w-8 h-8 bg-white/20 rounded-xl flex items-center justify-center">
                <MessageCircle className="w-4 h-4 text-white" />
              </div>
              <div>
                <p className="font-bold text-white text-sm">Asistente de Reservas</p>
                <p className="text-white/70 text-xs">{propertyLabel(selectedProperty)}</p>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <button
                onClick={fetchAll}
                disabled={loadingData}
                className="p-1.5 rounded-lg bg-white/10 hover:bg-white/20 transition-colors text-white"
                title="Actualizar datos"
              >
                <RefreshCw className={`w-3.5 h-3.5 ${loadingData ? 'animate-spin' : ''}`} />
              </button>
              <button
                onClick={() => setIsOpen(false)}
                className="p-1.5 rounded-lg bg-white/10 hover:bg-white/20 transition-colors text-white"
              >
                <X className="w-3.5 h-3.5" />
              </button>
            </div>
          </div>

          {/* Property selector */}
          <div className="flex gap-2 px-4 py-3 bg-slate-800/80 border-b border-white/5 flex-shrink-0">
            {(['los_dragos', 'la_esquinita'] as Property[]).map(p => (
              <button
                key={p}
                onClick={() => handlePropertySwitch(p)}
                className={`flex-1 flex items-center justify-center gap-1.5 py-2 px-3 rounded-xl text-xs font-semibold transition-all duration-200 ${
                  selectedProperty === p
                    ? (p === 'los_dragos'
                        ? 'bg-gradient-to-r from-emerald-600 to-teal-600 text-white shadow-lg shadow-emerald-500/30'
                        : 'bg-gradient-to-r from-amber-600 to-orange-600 text-white shadow-lg shadow-amber-500/30')
                    : 'bg-white/5 text-slate-400 hover:bg-white/10 hover:text-slate-200'
                }`}
              >
                <Home className="w-3 h-3" />
                {p === 'los_dragos' ? 'Los Dragos' : 'La Esquinita'}
              </button>
            ))}
          </div>

          {/* Messages */}
          <div className="flex-1 overflow-y-auto px-4 py-4 space-y-4">
            {messages.map(msg => (
              <div
                key={msg.id}
                className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
              >
                {msg.role === 'assistant' && (
                  <div className={`w-7 h-7 rounded-xl bg-gradient-to-br ${accentGradient} flex-shrink-0 flex items-center justify-center mr-2 mt-0.5`}>
                    <MessageCircle className="w-3.5 h-3.5 text-white" />
                  </div>
                )}
                <div
                  className={`max-w-[78%] px-4 py-3 rounded-2xl text-xs leading-relaxed ${
                    msg.role === 'user'
                      ? `${accentBg} ${accentText} border ${accentBorder} rounded-tr-sm`
                      : 'bg-slate-800 text-slate-100 rounded-tl-sm border border-white/5'
                  }`}
                >
                  <RenderMessage content={msg.content} />
                  <p className="text-[10px] opacity-40 mt-1.5 text-right">
                    {format(msg.timestamp, 'HH:mm')}
                  </p>
                </div>
              </div>
            ))}

            {/* Typing indicator */}
            {isTyping && (
              <div className="flex justify-start">
                <div className={`w-7 h-7 rounded-xl bg-gradient-to-br ${accentGradient} flex-shrink-0 flex items-center justify-center mr-2`}>
                  <MessageCircle className="w-3.5 h-3.5 text-white" />
                </div>
                <div className="bg-slate-800 border border-white/5 px-4 py-3 rounded-2xl rounded-tl-sm flex items-center gap-1">
                  <span className="w-1.5 h-1.5 bg-slate-400 rounded-full animate-bounce" style={{ animationDelay: '0ms' }} />
                  <span className="w-1.5 h-1.5 bg-slate-400 rounded-full animate-bounce" style={{ animationDelay: '150ms' }} />
                  <span className="w-1.5 h-1.5 bg-slate-400 rounded-full animate-bounce" style={{ animationDelay: '300ms' }} />
                </div>
              </div>
            )}

            <div ref={messagesEndRef} />
          </div>

          {/* Quick replies */}
          {messages.length <= 2 && (
            <div className="px-4 pb-2 flex gap-1.5 flex-wrap flex-shrink-0">
              {QUICK_REPLIES.map(qr => (
                <button
                  key={qr.text}
                  onClick={() => handleSend(qr.text)}
                  className={`px-3 py-1.5 rounded-xl text-[11px] font-medium bg-slate-800 text-slate-300 border border-white/5 hover:border-white/20 hover:text-white transition-all duration-150`}
                >
                  {qr.label}
                </button>
              ))}
            </div>
          )}

          {/* Input */}
          <div className="px-4 pb-4 pt-2 flex gap-2 flex-shrink-0 border-t border-white/5">
            <input
              ref={inputRef}
              type="text"
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={handleKeyDown}
              placeholder="Escribe tu pregunta…"
              className="flex-1 bg-slate-800 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-white placeholder-slate-500 outline-none focus:border-white/25 transition-colors"
            />
            <button
              onClick={() => handleSend()}
              disabled={!input.trim() || isTyping}
              className={`w-10 h-10 flex items-center justify-center rounded-xl bg-gradient-to-br ${accentGradient} text-white disabled:opacity-40 hover:opacity-90 transition-all duration-200 flex-shrink-0`}
            >
              <Send className="w-4 h-4" />
            </button>
          </div>
        </div>
      )}
    </>
  );
}
