'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { Search, Download, RefreshCw, Phone, MessageSquare, ChevronUp, ChevronDown, Eye, Trash2, CheckSquare, Square, ChevronLeft, ChevronRight, Users, Star, CalendarDays, FileSpreadsheet, ChevronDown as ChevronDownIcon, Bell, X } from 'lucide-react';
import StatusBadge from '@client/components/ui/StatusBadge';
import ConfirmModal from '@client/components/ui/ConfirmModal';
import SuccessModal from '@client/components/ui/SuccessModal';
import BookingDetailModal from './BookingDetailModal';
import { toast } from 'sonner';
import { listBookings, updateBooking, deleteBooking } from '@client/api/bookings';
import { useAuth } from '@client/contexts/AuthContext';
import { InlineTableSkeleton } from '@client/components/skeletons/PageSkeletons';
import { useLanguage } from '@client/contexts/LanguageContext';

  import type { Booking } from '@client/api/bookings';
  import type { Reservation } from './BookingDetailModal';

  function dbRowToReservation(b: Booking): Reservation {
    return {
      id: b.id,
      guestName: b.guestName,
      guestPhone: b.guestPhone || '',
      guestEmail: b.guestEmail,
      channel: (b.channel === 'voice' ? 'voice' : 'chat') as 'voice' | 'chat',
      status: b.status,
      partySize: b.partySize,
      date: b.date,
      time: b.time,
      tableNumber: b.tableNumber || '',
      zone: b.zone || '',
      specialRequests: b.specialRequests,
      occasion: b.occasion,
      dietaryNeeds: b.dietaryNeeds,
      aiNotes: b.aiNotes,
      aiConfidence: b.aiConfidence,
      confirmedAt: undefined,
      reminderSent: b.reminderSent || false,
      conversationId: b.conversationId || '',
      agentId: b.agentId || '',
      isVip: b.isVip || false,
      confirmationChannel: (['sms','email','both','none'].includes(b.confirmationChannel || '') ? b.confirmationChannel : 'none') as 'sms' | 'email' | 'both' | 'none',
    };
  }
  
function playNewBookingChime() {
  try {
    const AudioCtx = window.AudioContext || (window as any).webkitAudioContext;
    if (!AudioCtx) return;
    const ctx = new AudioCtx();
    const notes = [523.25, 659.25, 783.99];
    notes.forEach((freq, i) => {
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      osc.connect(gain);
      gain.connect(ctx.destination);
      osc.type = 'sine';
      osc.frequency.value = freq;
      const start = ctx.currentTime + i * 0.18;
      gain.gain.setValueAtTime(0, start);
      gain.gain.linearRampToValueAtTime(0.25, start + 0.04);
      gain.gain.exponentialRampToValueAtTime(0.001, start + 0.55);
      osc.start(start);
      osc.stop(start + 0.6);
    });
  } catch {
    // audio not available
  }
}

export default function BookingsTable() {
  const { restaurantId } = useAuth();
  const { t } = useLanguage();

  const STATUS_TABS = [
    { label: t('tableBooking.tabs.all', 'All'), value: 'all' },
    { label: t('tableBooking.status.pending', 'Pending'), value: 'pending' },
    { label: t('tableBooking.status.confirmed', 'Confirmed'), value: 'confirmed' },
    { label: t('tableBooking.status.seated', 'Seated'), value: 'seated' },
    { label: t('tableBooking.status.escalated', 'Escalated'), value: 'escalated' },
    { label: t('tableBooking.status.reminderSent', 'Reminder Sent'), value: 'reminder_sent' },
    { label: t('tableBooking.status.cancelled', 'Cancelled'), value: 'cancelled' },
    { label: t('tableBooking.status.noShow', 'No Show'), value: 'noshow' },
    { label: t('tableBooking.status.completed', 'Completed'), value: 'completed' },
  ];

  const [bookings, setBookings] = useState<Reservation[]>([]);
  const [loading, setLoading] = useState(true);
  const [activeTab, setActiveTab] = useState('all');
  const [search, setSearch] = useState('');
  const [sortField, setSortField] = useState('created_at');
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');
  const [page, setPage] = useState(1);
  const [totalCount, setTotalCount] = useState(0);
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [detailBooking, setDetailBooking] = useState<Reservation | null>(null);
  const [confirmDelete, setConfirmDelete] = useState(false);
  const [successModal, setSuccessModal] = useState<{ open: boolean; title: string }>({ open: false, title: '' });
  const [exportMenuOpen, setExportMenuOpen] = useState(false);
  const [newBookingAlert, setNewBookingAlert] = useState<Reservation | null>(null);
  const knownBookingIdsRef = useRef<Set<string> | null>(null);
  const PAGE_SIZE = 20;

  const fetchBookings = useCallback(async (silent = false) => {
    if (!restaurantId) { setLoading(false); return; }
    if (!silent) setLoading(true);
    try {
      const params: Record<string, string> = {
        page: String(page),
        limit: String(PAGE_SIZE),
        sort_field: sortField,
        sort_dir: sortDir,
      };
      if (activeTab !== 'all') params.status = activeTab;
      if (search) params.search = search;
      const result = await listBookings(params);
      const mapped = (result.bookings || []).map(dbRowToReservation);

      if (knownBookingIdsRef.current === null) {
        knownBookingIdsRef.current = new Set(mapped.map(b => b.id));
      } else {
        const incoming = mapped.find(b => !knownBookingIdsRef.current!.has(b.id));
        if (incoming) {
          mapped.forEach(b => knownBookingIdsRef.current!.add(b.id));
          playNewBookingChime();
          setNewBookingAlert(incoming);
        }
      }

      setBookings(mapped);
      setTotalCount(result.total || result.bookings?.length || 0);
    } catch (err: any) {
      if (!silent) toast.error(t('bookings.failedToLoad', 'Failed to load bookings') + ': ' + err.message);
    } finally {
      if (!silent) setLoading(false);
    }
  }, [restaurantId, activeTab, search, sortField, sortDir, page]);

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

  useEffect(() => {
    const interval = setInterval(() => fetchBookings(true), 30000);
    return () => clearInterval(interval);
  }, [fetchBookings]);

  const handleUpdateStatus = async (bookingId: string, newStatus: string) => {
    try {
      await updateBooking(bookingId, { status: newStatus });
      setBookings(prev => prev.map(b => b.id === bookingId ? { ...b, status: newStatus } : b));
      toast.success(t('bookings.statusUpdated', 'Booking status updated'));
    } catch (err: any) {
      toast.error(t('bookings.failedToUpdate', 'Failed to update booking') + ': ' + err.message);
    }
  };

  const handleDelete = async (ids: string[]) => {
    try {
      await Promise.all(ids.map(id => deleteBooking(id)));
      setBookings(prev => prev.filter(b => !ids.includes(b.id)));
      setSelectedIds([]);
      setConfirmDelete(false);
      setSuccessModal({ open: true, title: `${ids.length} booking${ids.length > 1 ? 's' : ''} deleted` });
    } catch (err: any) {
      toast.error(t('bookings.failedToDelete', 'Failed to delete bookings') + ': ' + err.message);
    }
  };

  const handleSort = (field: string) => {
    if (sortField === field) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortField(field); setSortDir('desc'); }
  };

  const toggleRow = (id: string) => setSelectedIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
  const toggleAll = () => setSelectedIds(selectedIds.length === bookings.length ? [] : bookings.map(b => b.id));

  const exportCSV = () => {
    const data = selectedIds.length > 0 ? bookings.filter(b => selectedIds.includes(b.id)) : bookings;
    const headers = [t('bookings.csv.id', 'ID'), t('bookings.csv.guest', 'Guest'), t('bookings.csv.partySize', 'Party Size'), t('bookings.csv.date', 'Date'), t('bookings.csv.time', 'Time'), t('bookings.csv.table', 'Table'), t('bookings.csv.status', 'Status'), t('bookings.csv.channel', 'Channel')];
    const rows = data.map(b => [b.id, b.guestName, b.partySize, b.date, b.time, b.tableNumber, b.status, b.channel]);
    const csv = [headers, ...rows].map(r => r.map(v => `"${String(v).replace(/"/g, '""')}"`).join(',')).join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = `bookings-${new Date().toISOString().slice(0, 10)}.csv`; a.click();
    URL.revokeObjectURL(url);
    setExportMenuOpen(false);
    toast.success(t('bookings.exported', 'Bookings exported'));
  };

  const totalPages = Math.ceil(totalCount / PAGE_SIZE);
  const SortIcon = ({ field }: { field: string }) => (
    sortField === field ? sortDir === 'asc' ? <ChevronUp size={12} /> : <ChevronDown size={12} /> : <ChevronDown size={12} style={{ opacity: 0.3 }} />
  );

  return (
    <div className="card overflow-hidden">
      {/* New booking alert dialog */}
      {newBookingAlert && (
        <div className="fixed bottom-6 right-6 z-50 w-80 rounded-2xl shadow-xl overflow-hidden" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--primary))' }}>
          <div className="flex items-center justify-between px-4 py-3" style={{ backgroundColor: 'hsl(var(--primary-light))', borderBottom: '1px solid hsl(var(--primary))' }}>
            <div className="flex items-center gap-2">
              <Bell size={15} style={{ color: 'hsl(var(--primary))' }} />
              <span className="text-sm font-bold" style={{ color: 'hsl(var(--primary))' }}>{t('tableBooking.newReservation', 'New Reservation')}</span>
            </div>
            <button className="btn-ghost p-1" onClick={() => setNewBookingAlert(null)}><X size={14} /></button>
          </div>
          <div className="px-4 py-3 space-y-1">
            <p className="text-sm font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{newBookingAlert.guestName}</p>
            <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
              {t('tableBooking.newReservationSub', '{count} guests · {date} {time}', { count: newBookingAlert.partySize, date: newBookingAlert.date, time: newBookingAlert.time })}
            </p>
            {newBookingAlert.specialRequests && (
              <p className="text-xs italic" style={{ color: 'hsl(var(--muted-foreground))' }}>"{newBookingAlert.specialRequests}"</p>
            )}
          </div>
          <div className="px-4 pb-3 flex gap-2">
            <button
              className="btn-primary text-xs py-1.5 flex-1 justify-center"
              onClick={() => { setDetailBooking(newBookingAlert); setNewBookingAlert(null); }}
            >
              {t('tableBooking.viewBooking', 'View Booking')}
            </button>
            <button className="btn-secondary text-xs py-1.5" onClick={() => setNewBookingAlert(null)}>{t('common.dismiss', 'Dismiss')}</button>
          </div>
        </div>
      )}

      <div className="flex overflow-x-auto" style={{ borderBottom: '1px solid hsl(var(--border))' }}>
        {STATUS_TABS.map(tab => (
          <button key={tab.value} onClick={() => { setActiveTab(tab.value); setPage(1); }} className="px-4 py-3 text-xs font-semibold whitespace-nowrap transition-colors" style={{ color: activeTab === tab.value ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))', borderBottom: activeTab === tab.value ? '2px solid hsl(var(--primary))' : '2px solid transparent' }}>
            {tab.label}
          </button>
        ))}
      </div>

      <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 p-4" style={{ borderBottom: '1px solid hsl(var(--border))' }}>
        <div className="flex items-center gap-3 flex-1">
          <div className="relative max-w-xs flex-1">
            <Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2" style={{ color: 'hsl(var(--muted-foreground))' }} />
            <input className="input-base pl-9 text-sm" placeholder={t('tableBooking.searchPlaceholder', 'Search by guest name...')} value={search} onChange={e => { setSearch(e.target.value); setPage(1); }} />
          </div>
          {selectedIds.length > 0 && (
            <span className="text-xs font-medium px-2 py-1 rounded-lg" style={{ backgroundColor: 'hsl(var(--primary-light))', color: 'hsl(var(--primary))' }}>
              {t('common.selectedCount', '{count} selected', { count: selectedIds.length })}
            </span>
          )}
        </div>
        <div className="flex items-center gap-2">
          {selectedIds.length > 0 && (
            <button className="btn-secondary text-xs py-1.5" style={{ color: 'hsl(var(--danger))' }} onClick={() => setConfirmDelete(true)}>
              <Trash2 size={13} /> {t('common.delete', 'Delete')}
            </button>
          )}
          <div className="relative">
            <button className="btn-secondary text-xs py-1.5" onClick={() => setExportMenuOpen(!exportMenuOpen)}>
              <Download size={13} /> {t('common.export', 'Export')} <ChevronDownIcon size={12} />
            </button>
            {exportMenuOpen && (
              <div className="absolute right-0 top-full mt-1 w-40 rounded-xl shadow-lg z-20 overflow-hidden" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
                <button className="flex items-center gap-2 w-full px-3 py-2.5 text-xs hover:bg-black/5" onClick={exportCSV}>
                  <FileSpreadsheet size={13} /> {t('common.exportCsv', 'Export CSV')}
                </button>
              </div>
            )}
          </div>
          <button className="btn-secondary text-xs py-1.5" onClick={() => fetchBookings()}>
            <RefreshCw size={13} className={loading ? 'animate-spin' : ''} />
          </button>
        </div>
      </div>

      {loading ? (
        <InlineTableSkeleton columns={6} rows={8} />
      ) : bookings.length === 0 ? (
        <div className="text-center py-16" style={{ color: 'hsl(var(--muted-foreground))' }}>
          <CalendarDays size={32} className="mx-auto mb-3 opacity-30" />
          <p className="font-medium">{t('tableBooking.noBookingsFound', 'No bookings found')}</p>
          <p className="text-xs mt-1">{t('tableBooking.noBookingsSub', 'Bookings will appear here when customers make reservations')}</p>
        </div>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full">
            <thead>
              <tr style={{ borderBottom: '1px solid hsl(var(--border))' }}>
                <th className="px-4 py-3 w-10">
                  <button onClick={toggleAll}>
                    {selectedIds.length === bookings.length && bookings.length > 0 ? <CheckSquare size={15} style={{ color: 'hsl(var(--primary))' }} /> : <Square size={15} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                  </button>
                </th>
                {[
                  { label: t('tableBooking.cols.guest', 'Guest'), field: 'guest_name' },
                  { label: t('tableBooking.cols.party', 'Party'), field: 'party_size' },
                  { label: t('tableBooking.cols.dateTime', 'Date & Time'), field: 'booking_date' },
                  { label: t('tableBooking.cols.table', 'Table'), field: 'table_no' },
                  { label: t('tableBooking.cols.channel', 'Channel'), field: 'channel' },
                  { label: t('tableBooking.cols.status', 'Status'), field: 'status' },
                  { label: '', field: null },
                ].map(col => (
                  <th key={col.label} className="text-left px-4 py-3 text-xs font-semibold uppercase tracking-wider" style={{ color: 'hsl(var(--muted-foreground))', cursor: col.field ? 'pointer' : 'default' }} onClick={() => col.field && handleSort(col.field)}>
                    <span className="flex items-center gap-1">{col.label}{col.field && <SortIcon field={col.field} />}</span>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {bookings.map((booking, idx) => (
                <tr key={booking.id} className="table-row-hover" style={{ borderBottom: idx < bookings.length - 1 ? '1px solid hsl(var(--border))' : 'none' }}>
                  <td className="px-4 py-3">
                    <button onClick={() => toggleRow(booking.id)}>
                      {selectedIds.includes(booking.id) ? <CheckSquare size={15} style={{ color: 'hsl(var(--primary))' }} /> : <Square size={15} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                    </button>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-2">
                      <div className="w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-bold shrink-0" style={{ background: 'linear-gradient(135deg, hsl(var(--primary)), hsl(22, 89%, 36%))' }}>
                        {booking.guestName.split(' ').map((n: string) => n[0]).join('').slice(0, 2)}
                      </div>
                      <div>
                        <p className="font-medium text-sm" style={{ color: 'hsl(var(--foreground))' }}>
                          {booking.guestName}
                          {booking.isVip && <Star size={11} className="inline ml-1" style={{ color: 'hsl(38, 92%, 40%)' }} />}
                        </p>
                        <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{booking.guestPhone}</p>
                      </div>
                    </div>
                  </td>
                  <td className="px-4 py-3">
                    <span className="flex items-center gap-1.5 text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>
                      <Users size={13} style={{ color: 'hsl(var(--muted-foreground))' }} /> {booking.partySize}
                    </span>
                  </td>
                  <td className="px-4 py-3">
                    <p className="text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>{booking.date}</p>
                    <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{booking.time}</p>
                  </td>
                  <td className="px-4 py-3 text-sm" style={{ color: 'hsl(var(--foreground))' }}>{booking.tableNumber}</td>
                  <td className="px-4 py-3">
                    <span className="flex items-center gap-1.5 text-xs font-medium capitalize" style={{ color: 'hsl(var(--foreground-secondary))' }}>
                      {booking.channel === 'voice' ? <Phone size={12} /> : <MessageSquare size={12} />} {booking.channel === 'voice' ? t('tableBooking.channels.voice', 'Voice') : t('tableBooking.channels.chat', 'Chat')}
                    </span>
                  </td>
                  <td className="px-4 py-3"><StatusBadge status={booking.status} /></td>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-1">
                      <button className="btn-ghost p-1.5" onClick={() => setDetailBooking(booking)} title={t('common.viewDetails', 'View details')}><Eye size={14} /></button>
                      <button className="btn-ghost p-1.5" style={{ color: 'hsl(var(--danger))' }} onClick={() => { setSelectedIds([booking.id]); setConfirmDelete(true); }} title={t('common.delete', 'Delete')}><Trash2 size={14} /></button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {totalPages > 1 && (
        <div className="flex items-center justify-between px-4 py-3" style={{ borderTop: '1px solid hsl(var(--border))' }}>
          <span className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
            {t('common.paginationInfo', 'Showing {start}–{end} of {total}', { start: (page - 1) * PAGE_SIZE + 1, end: Math.min(page * PAGE_SIZE, totalCount), total: totalCount })}
          </span>
          <div className="flex items-center gap-2">
            <button className="btn-ghost p-1.5" disabled={page === 1} onClick={() => setPage(p => p - 1)}><ChevronLeft size={15} /></button>
            <span className="text-xs font-medium" style={{ color: 'hsl(var(--foreground))' }}>{page} / {totalPages}</span>
            <button className="btn-ghost p-1.5" disabled={page === totalPages} onClick={() => setPage(p => p + 1)}><ChevronRight size={15} /></button>
          </div>
        </div>
      )}

      <BookingDetailModal reservation={detailBooking} isOpen={detailBooking !== null} onClose={() => setDetailBooking(null)} onStatusChange={(id, status) => handleUpdateStatus(id, status)} />
      <ConfirmModal isOpen={confirmDelete} onClose={() => setConfirmDelete(false)} onConfirm={() => handleDelete(selectedIds)} title={t('tableBooking.deleteTitle', 'Delete Bookings')} description={t('tableBooking.deleteConfirm', 'Are you sure you want to delete {count} booking{plural}? This cannot be undone.', { count: selectedIds.length, plural: selectedIds.length > 1 ? 's' : '' })} confirmLabel={t('common.delete', 'Delete')} variant="danger" />
      <SuccessModal isOpen={successModal.open} title={successModal.title} onClose={() => setSuccessModal({ open: false, title: '' })} />
    </div>
  );
}
