import React, { useState, useMemo, useRef } from 'react';
import { useOutletContext, Link } from 'react-router-dom';
import { User, Business, Appointment } from '../../types';
import { useAppointments, useUpdateAppointment } from '../../hooks/useAppointments';
import { useServices } from '../../hooks/useServices';
import { Calendar, Clock, X, FileText, Tag, Loader2, DollarSign, CreditCard, Printer, Receipt } from 'lucide-react';
import Portal from '../../components/Portal';

const AppointmentList: React.FC<{ user: User, business: Business }> = ({ user, business }) => {
    const [activeTab, setActiveTab] = useState<'upcoming' | 'past'>('upcoming');
    const [selectedAppointment, setSelectedAppointment] = useState<Appointment | null>(null);

    // Fetch appointments from API - backend filters for current customer
    const { data: appointments = [], isLoading, error } = useAppointments();
    const { data: services = [] } = useServices();
    const updateAppointment = useUpdateAppointment();

    // Sort appointments by start time (newest first)
    const sortedAppointments = useMemo(() =>
        [...appointments].sort((a, b) => b.startTime.getTime() - a.startTime.getTime()),
        [appointments]
    );

    const upcomingAppointments = sortedAppointments.filter(apt => new Date(apt.startTime) >= new Date() && apt.status !== 'CANCELLED');
    const pastAppointments = sortedAppointments.filter(apt => new Date(apt.startTime) < new Date() || apt.status === 'CANCELLED');

    const handleCancel = async (appointment: Appointment) => {
        const hoursBefore = (new Date(appointment.startTime).getTime() - new Date().getTime()) / 3600000;
        if (hoursBefore < business.cancellationWindowHours) {
            const service = services.find(s => s.id === appointment.serviceId);
            const fee = service ? (parseFloat(service.price) * (business.lateCancellationFeePercent / 100)).toFixed(2) : 'a fee';
            if (!window.confirm(`Cancelling within the ${business.cancellationWindowHours}-hour window may incur a fee of $${fee}. Are you sure?`)) return;
        } else {
            if (!window.confirm("Are you sure you want to cancel this appointment?")) return;
        }
        try {
            await updateAppointment.mutateAsync({ id: appointment.id, updates: { status: 'CANCELLED' } });
        } catch (err) {
            console.error('Failed to cancel appointment:', err);
            alert('Failed to cancel appointment. Please try again.');
        }
    };

    // Helper to create receipt row elements
    const createReceiptRow = (doc: Document, label: string, value: string, className?: string): HTMLDivElement => {
        const row = doc.createElement('div');
        row.className = 'receipt-row' + (className ? ' ' + className : '');
        const labelSpan = doc.createElement('span');
        labelSpan.className = 'label';
        labelSpan.textContent = label;
        const valueSpan = doc.createElement('span');
        valueSpan.className = 'value' + (className ? ' ' + className : '');
        valueSpan.textContent = value;
        row.appendChild(labelSpan);
        row.appendChild(valueSpan);
        return row;
    };

    const handlePrintReceipt = (appointment: Appointment) => {
        const service = services.find(s => s.id === appointment.serviceId);

        // Create an iframe for printing
        const iframe = document.createElement('iframe');
        iframe.style.position = 'absolute';
        iframe.style.width = '0';
        iframe.style.height = '0';
        iframe.style.border = 'none';
        document.body.appendChild(iframe);

        const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
        if (!iframeDoc) {
            alert('Unable to generate receipt. Please try again.');
            document.body.removeChild(iframe);
            return;
        }

        // Build HTML structure using DOM methods
        const style = iframeDoc.createElement('style');
        style.textContent = `
            body { font-family: system-ui, -apple-system, sans-serif; padding: 40px; max-width: 600px; margin: 0 auto; }
            h1 { font-size: 24px; margin-bottom: 8px; }
            .business-name { color: #666; margin-bottom: 24px; }
            .receipt-section { margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #eee; }
            .receipt-row { display: flex; justify-content: space-between; margin-bottom: 8px; }
            .label { color: #666; }
            .value { font-weight: 600; }
            .total { font-size: 18px; font-weight: bold; }
            .paid { color: #16a34a; }
            .due { color: #ea580c; }
            .footer { margin-top: 32px; text-align: center; color: #999; font-size: 12px; }
        `;
        iframeDoc.head.appendChild(style);

        const title = iframeDoc.createElement('title');
        title.textContent = `Receipt - ${service?.name || 'Appointment'}`;
        iframeDoc.head.appendChild(title);

        // Header
        const h1 = iframeDoc.createElement('h1');
        h1.textContent = 'Receipt';
        iframeDoc.body.appendChild(h1);

        const businessName = iframeDoc.createElement('div');
        businessName.className = 'business-name';
        businessName.textContent = business.name;
        iframeDoc.body.appendChild(businessName);

        // Appointment Details Section
        const detailsSection = iframeDoc.createElement('div');
        detailsSection.className = 'receipt-section';
        detailsSection.appendChild(createReceiptRow(iframeDoc, 'Service', service?.name || 'Appointment'));
        detailsSection.appendChild(createReceiptRow(iframeDoc, 'Date', new Date(appointment.startTime).toLocaleDateString()));
        detailsSection.appendChild(createReceiptRow(iframeDoc, 'Time', new Date(appointment.startTime).toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' })));
        detailsSection.appendChild(createReceiptRow(iframeDoc, 'Duration', `${appointment.durationMinutes} minutes`));
        detailsSection.appendChild(createReceiptRow(iframeDoc, 'Status', appointment.status.replace(/_/g, ' ')));
        iframeDoc.body.appendChild(detailsSection);

        // Payment Section
        const paymentSection = iframeDoc.createElement('div');
        paymentSection.className = 'receipt-section';

        if (service?.price) {
            const priceText = appointment.isVariablePricing ? 'Variable' : `$${service.price}`;
            paymentSection.appendChild(createReceiptRow(iframeDoc, 'Service Price', priceText));
        }
        if (appointment.depositAmount && appointment.depositAmount > 0) {
            paymentSection.appendChild(createReceiptRow(iframeDoc, 'Deposit Paid', `-$${appointment.depositAmount.toFixed(2)}`, 'paid'));
        }
        if (appointment.finalPrice && appointment.isVariablePricing) {
            paymentSection.appendChild(createReceiptRow(iframeDoc, 'Final Price', `$${appointment.finalPrice.toFixed(2)}`));
        }
        if (appointment.remainingBalance && appointment.remainingBalance > 0 && !['COMPLETED', 'PAID'].includes(appointment.status)) {
            paymentSection.appendChild(createReceiptRow(iframeDoc, 'Amount Due', `$${appointment.remainingBalance.toFixed(2)}`, 'total due'));
        }
        if (['COMPLETED', 'PAID'].includes(appointment.status) && (!appointment.remainingBalance || appointment.remainingBalance <= 0)) {
            paymentSection.appendChild(createReceiptRow(iframeDoc, 'Status', 'Paid in Full', 'total paid'));
        }
        iframeDoc.body.appendChild(paymentSection);

        // Footer
        const footer = iframeDoc.createElement('div');
        footer.className = 'footer';
        const thankYou = iframeDoc.createElement('p');
        thankYou.textContent = 'Thank you for your business!';
        const appointmentId = iframeDoc.createElement('p');
        appointmentId.textContent = `Appointment ID: ${appointment.id}`;
        footer.appendChild(thankYou);
        footer.appendChild(appointmentId);
        iframeDoc.body.appendChild(footer);

        // Print and cleanup
        setTimeout(() => {
            iframe.contentWindow?.print();
            setTimeout(() => document.body.removeChild(iframe), 1000);
        }, 250);
    };

    if (isLoading) {
        return (
            <div className="mt-8 flex items-center justify-center py-12">
                <Loader2 className="w-8 h-8 animate-spin text-brand-500" />
            </div>
        );
    }

    if (error) {
        return (
            <div className="mt-8 text-center py-8 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800">
                <p className="text-red-600 dark:text-red-400">Failed to load appointments. Please try again later.</p>
            </div>
        );
    }

    return (
        <div className="mt-8">
            <h2 className="text-xl font-bold mb-4">Your Appointments</h2>
            <div className="flex items-center gap-2 mb-6 p-1 bg-gray-100 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 self-start">
                <button onClick={() => setActiveTab('upcoming')} className={`px-4 py-2 text-sm font-medium rounded-md ${activeTab === 'upcoming' ? 'bg-brand-500 text-white' : 'text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'}`}>Upcoming</button>
                <button onClick={() => setActiveTab('past')} className={`px-4 py-2 text-sm font-medium rounded-md ${activeTab === 'past' ? 'bg-brand-500 text-white' : 'text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'}`}>Past</button>
            </div>
            <div className="space-y-4">
                {(activeTab === 'upcoming' ? upcomingAppointments : pastAppointments).map(apt => {
                    const service = services.find(s => s.id === apt.serviceId);
                    return (
                        <div
                            key={apt.id}
                            onClick={() => setSelectedAppointment(apt)}
                            className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 flex items-center justify-between cursor-pointer hover:border-brand-300 dark:hover:border-brand-600 hover:shadow-md transition-all"
                        >
                            <div>
                                <h3 className="font-semibold">{service?.name || 'Appointment'}</h3>
                                <p className="text-sm text-gray-500">{new Date(apt.startTime).toLocaleString()}</p>
                            </div>
                            <div className="flex items-center gap-3">
                                <span className={`text-xs font-medium px-2 py-1 rounded-full ${
                                    apt.status === 'SCHEDULED' ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' :
                                    apt.status === 'PENDING_DEPOSIT' ? 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' :
                                    apt.status === 'CANCELLED' ? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400' :
                                    apt.status === 'COMPLETED' ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' :
                                    'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300'
                                }`}>
                                    {apt.status.replace(/_/g, ' ')}
                                </span>
                            </div>
                        </div>
                    );
                })}
                 {(activeTab === 'upcoming' ? upcomingAppointments : pastAppointments).length === 0 && (
                    <div className="text-center py-8 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
                        <p className="text-gray-500 dark:text-gray-400">No {activeTab} appointments found.</p>
                    </div>
                )}
            </div>

            {/* Appointment Detail Modal */}
            {selectedAppointment && (
                <Portal>
                    <div
                        className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm"
                        onClick={() => setSelectedAppointment(null)}
                    >
                        <div
                            className="w-full max-w-md bg-white dark:bg-gray-800 rounded-xl shadow-xl border border-gray-200 dark:border-gray-700 overflow-hidden"
                            onClick={e => e.stopPropagation()}
                        >
                            {/* Header */}
                            <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gradient-to-r from-brand-50 to-brand-100 dark:from-brand-900/30 dark:to-brand-800/30">
                                <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
                                    Appointment Details
                                </h3>
                                <button
                                    onClick={() => setSelectedAppointment(null)}
                                    className="p-1 text-gray-400 hover:bg-white/50 dark:hover:bg-gray-700/50 rounded-full transition-colors"
                                >
                                    <X size={20} />
                                </button>
                            </div>

                            {/* Content */}
                            <div className="p-6 space-y-4">
                                {/* Service */}
                                <div className="flex items-start gap-3 p-4 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                    <div className="flex-shrink-0 w-10 h-10 rounded-full bg-brand-100 dark:bg-brand-900/50 flex items-center justify-center">
                                        <Tag size={20} className="text-brand-600 dark:text-brand-400" />
                                    </div>
                                    <div className="flex-1 min-w-0">
                                        <p className="text-sm font-medium text-gray-500 dark:text-gray-400">Service</p>
                                        <p className="text-lg font-semibold text-gray-900 dark:text-white">
                                            {services.find(s => s.id === selectedAppointment.serviceId)?.name || 'Appointment'}
                                        </p>
                                    </div>
                                </div>

                                {/* Date, Time & Duration */}
                                <div className="grid grid-cols-2 gap-4">
                                    <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                        <div className="flex items-center gap-2 mb-1">
                                            <Calendar size={14} className="text-gray-400" />
                                            <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Date</p>
                                        </div>
                                        <p className="text-sm font-semibold text-gray-900 dark:text-white">
                                            {new Date(selectedAppointment.startTime).toLocaleDateString(undefined, {
                                                weekday: 'short',
                                                month: 'short',
                                                day: 'numeric',
                                                year: 'numeric'
                                            })}
                                        </p>
                                    </div>
                                    <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                        <div className="flex items-center gap-2 mb-1">
                                            <Clock size={14} className="text-gray-400" />
                                            <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Time</p>
                                        </div>
                                        <p className="text-sm font-semibold text-gray-900 dark:text-white">
                                            {new Date(selectedAppointment.startTime).toLocaleTimeString(undefined, {
                                                hour: 'numeric',
                                                minute: '2-digit'
                                            })}
                                        </p>
                                    </div>
                                </div>

                                {/* Duration & Status */}
                                <div className="grid grid-cols-2 gap-4">
                                    <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                        <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1">Duration</p>
                                        <p className="text-sm font-semibold text-gray-900 dark:text-white">
                                            {selectedAppointment.durationMinutes} minutes
                                        </p>
                                    </div>
                                    <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                        <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1">Status</p>
                                        <span className={`inline-flex text-xs font-medium px-2 py-1 rounded-full ${
                                            selectedAppointment.status === 'SCHEDULED' ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' :
                                            selectedAppointment.status === 'PENDING_DEPOSIT' ? 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' :
                                            selectedAppointment.status === 'CANCELLED' ? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400' :
                                            selectedAppointment.status === 'COMPLETED' ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' :
                                            'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300'
                                        }`}>
                                            {selectedAppointment.status.replace(/_/g, ' ')}
                                        </span>
                                    </div>
                                </div>

                                {/* Notes */}
                                {selectedAppointment.notes && (
                                    <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
                                        <div className="flex items-center gap-2 mb-1">
                                            <FileText size={14} className="text-gray-400" />
                                            <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Notes</p>
                                        </div>
                                        <p className="text-sm text-gray-700 dark:text-gray-200">{selectedAppointment.notes}</p>
                                    </div>
                                )}

                                {/* Payment Information */}
                                {(() => {
                                    const service = services.find(s => s.id === selectedAppointment.serviceId);
                                    const hasPaymentData = selectedAppointment.depositAmount || selectedAppointment.finalPrice ||
                                                          selectedAppointment.finalChargeTransactionId || service?.price;

                                    if (!hasPaymentData) return null;

                                    // Calculate payment made (final charge minus deposit that was already applied)
                                    const paymentMade = selectedAppointment.finalChargeTransactionId && selectedAppointment.finalPrice
                                        ? (selectedAppointment.finalPrice - (selectedAppointment.depositAmount || 0))
                                        : null;

                                    return (
                                        <div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800">
                                            <div className="flex items-center gap-2 mb-3">
                                                <DollarSign size={16} className="text-green-600 dark:text-green-400" />
                                                <p className="text-sm font-semibold text-green-800 dark:text-green-300">Payment Summary</p>
                                            </div>
                                            <div className="space-y-2">
                                                {/* Service Price */}
                                                {service?.price && (
                                                    <div className="flex justify-between text-sm">
                                                        <span className="text-gray-600 dark:text-gray-400">Service Price</span>
                                                        <span className="font-medium text-gray-900 dark:text-white">
                                                            {selectedAppointment.isVariablePricing ? 'Variable' : `$${service.price}`}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Final Price (for variable pricing after completion) */}
                                                {selectedAppointment.finalPrice && selectedAppointment.isVariablePricing && (
                                                    <div className="flex justify-between text-sm">
                                                        <span className="text-gray-600 dark:text-gray-400">Final Price</span>
                                                        <span className="font-medium text-gray-900 dark:text-white">
                                                            ${selectedAppointment.finalPrice.toFixed(2)}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Deposit Paid */}
                                                {selectedAppointment.depositAmount && selectedAppointment.depositAmount > 0 && (
                                                    <div className="flex justify-between text-sm">
                                                        <span className="text-gray-600 dark:text-gray-400 flex items-center gap-1">
                                                            <CreditCard size={12} />
                                                            Deposit Paid
                                                        </span>
                                                        <span className="font-medium text-green-600 dark:text-green-400">
                                                            ${selectedAppointment.depositAmount.toFixed(2)}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Payment Made (final charge) */}
                                                {paymentMade && paymentMade > 0 && (
                                                    <div className="flex justify-between text-sm">
                                                        <span className="text-gray-600 dark:text-gray-400 flex items-center gap-1">
                                                            <CreditCard size={12} />
                                                            Payment Made
                                                        </span>
                                                        <span className="font-medium text-green-600 dark:text-green-400">
                                                            ${paymentMade.toFixed(2)}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Amount Due */}
                                                {selectedAppointment.remainingBalance && selectedAppointment.remainingBalance > 0 && (
                                                    <div className="flex justify-between text-sm pt-2 border-t border-green-200 dark:border-green-700">
                                                        <span className="font-medium text-gray-700 dark:text-gray-300">
                                                            {['COMPLETED', 'PAID'].includes(selectedAppointment.status) ? 'Balance Due' : 'Amount Due at Service'}
                                                        </span>
                                                        <span className="font-bold text-orange-600 dark:text-orange-400">
                                                            ${selectedAppointment.remainingBalance.toFixed(2)}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Overpaid / Refund Due */}
                                                {selectedAppointment.overpaidAmount && selectedAppointment.overpaidAmount > 0 && (
                                                    <div className="flex justify-between text-sm pt-2 border-t border-green-200 dark:border-green-700">
                                                        <span className="font-medium text-gray-700 dark:text-gray-300">Refund Due</span>
                                                        <span className="font-bold text-blue-600 dark:text-blue-400">
                                                            ${selectedAppointment.overpaidAmount.toFixed(2)}
                                                        </span>
                                                    </div>
                                                )}

                                                {/* Fully Paid indicator */}
                                                {['COMPLETED', 'PAID'].includes(selectedAppointment.status) &&
                                                 (!selectedAppointment.remainingBalance || selectedAppointment.remainingBalance <= 0) && (
                                                    <div className="flex justify-between text-sm pt-2 border-t border-green-200 dark:border-green-700">
                                                        <span className="font-medium text-green-700 dark:text-green-300">Status</span>
                                                        <span className="font-bold text-green-600 dark:text-green-400">
                                                            Paid in Full
                                                        </span>
                                                    </div>
                                                )}
                                            </div>
                                        </div>
                                    );
                                })()}

                                {/* TODO: Add View Contracts button when contracts feature is linked to appointments */}

                                {/* Action Buttons */}
                                <div className="pt-4 flex justify-between border-t border-gray-200 dark:border-gray-700">
                                    <div className="flex gap-2">
                                        <button
                                            onClick={() => setSelectedAppointment(null)}
                                            className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
                                        >
                                            Close
                                        </button>
                                        <button
                                            onClick={() => handlePrintReceipt(selectedAppointment)}
                                            className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors flex items-center gap-2"
                                        >
                                            <Printer size={16} />
                                            Print Receipt
                                        </button>
                                    </div>
                                    {new Date(selectedAppointment.startTime) >= new Date() && selectedAppointment.status !== 'CANCELLED' && (
                                        <button
                                            onClick={() => {
                                                handleCancel(selectedAppointment);
                                                setSelectedAppointment(null);
                                            }}
                                            disabled={updateAppointment.isPending}
                                            className="px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50"
                                        >
                                            {updateAppointment.isPending ? 'Cancelling...' : 'Cancel Appointment'}
                                        </button>
                                    )}
                                </div>
                            </div>
                        </div>
                    </div>
                </Portal>
            )}
        </div>
    );
};

const CustomerDashboard: React.FC = () => {
  const { user, business } = useOutletContext<{ user: User, business: Business }>();

  return (
    <div className="max-w-4xl mx-auto">
      <div className="mb-8">
        <h1 className="text-3xl font-bold text-gray-900 dark:text-white">Welcome, {user.name.split(' ')[0]}!</h1>
        <p className="text-gray-500 dark:text-gray-400">View your upcoming appointments and manage your account.</p>
      </div>

      <AppointmentList user={user} business={business} />
    </div>
  );
};

export default CustomerDashboard;