import { useState, useEffect, useMemo } from 'preact/hooks';
import { fetchSlots, submitBooking } from './api';
import { departmentIcon } from './icons';
import { IconSpan } from './icon-span';
import { useWidgetStore } from './store';
import type { Doctor, TimeSlot } from './types';

type Step = 'branch' | 'department' | 'doctor' | 'datetime' | 'details' | 'success';

export const Booking = () => {
    const {
        visitor,
        updateVisitor,
        captchaToken,
        bookingPrefill,
        setBookingPrefill,
        doctors,
        doctorsLoading,
        doctorsError,
        branches,
        selectedBranch,
        setSelectedBranch,
    } = useWidgetStore();

    // Start on the branch step only if the visitor actually has a choice to
    // make. Single-branch hospitals and chat-prefilled sessions skip it.
    const needsBranchStep = branches.length > 1 && !selectedBranch;
    const [step, setStep] = useState<Step>(needsBranchStep ? 'branch' : 'department');
    const [selectedDept, setSelectedDept] = useState('');
    const [selectedDoctor, setSelectedDoctor] = useState<Doctor | null>(null);
    const [selectedDate, setSelectedDate] = useState('');
    const [slots, setSlots] = useState<TimeSlot[]>([]);
    const [selectedSlot, setSelectedSlot] = useState('');
    const [complaint, setComplaint] = useState('');
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');
    const [reference, setReference] = useState('');

    // Scope the roster to the selected branch up front. Every downstream
    // derivation (departments list, doctor filter) works off this.
    const branchDoctors = useMemo(() => {
        if (!selectedBranch) return doctors;
        const needle = selectedBranch.toLowerCase();
        return doctors.filter(d =>
            String(d.clinic?.clinicName ?? '').toLowerCase().includes(needle),
        );
    }, [doctors, selectedBranch]);

    // Derive department list from the branch-scoped roster.
    const departments = useMemo(
        () => [...new Set(branchDoctors.map(d => d.department).filter(Boolean))] as string[],
        [branchDoctors],
    );

    const filteredDoctors = selectedDept
        ? branchDoctors.filter(d => d.department === selectedDept)
        : [];

    // Surface a doctors-load error if the roster failed to fetch.
    useEffect(() => {
        if (doctorsError) setError(doctorsError);
    }, [doctorsError]);

    // Consume any booking prefill from chat → jump straight to the details form.
    // Also locks the branch to the picked doctor's clinic so the visitor sees
    // the right header badge when they land here.
    useEffect(() => {
        if (!bookingPrefill || doctors.length === 0) return;
        const doc = doctors.find(d => d.id === bookingPrefill.doctorId);
        if (!doc) return;
        if (doc.clinic?.clinicName && !selectedBranch) {
            setSelectedBranch(doc.clinic.clinicName);
        }
        setSelectedDept(doc.department);
        setSelectedDoctor(doc);
        setSelectedDate(bookingPrefill.date);
        setSelectedSlot(bookingPrefill.time);
        setStep('details');
        setBookingPrefill(null);
    }, [bookingPrefill, doctors]);

    const handleDoctorSelect = (doc: Doctor) => {
        setSelectedDoctor(doc);
        setSelectedDate(new Date().toISOString().split('T')[0]);
        setStep('datetime');
    };

    useEffect(() => {
        if (selectedDoctor && selectedDate) {
            fetchSlots(selectedDoctor.id, selectedDate).then(setSlots).catch(() => {});
        }
    }, [selectedDoctor, selectedDate]);

    const handleBook = async () => {
        if (!selectedDoctor || !selectedSlot || !visitor.name.trim() || !visitor.phone.trim()) return;
        setLoading(true);
        setError('');
        try {
            const scheduledAt = `${selectedDate}T${selectedSlot}:00`;
            const result = await submitBooking({
                departmentId: selectedDept,
                doctorId: selectedDoctor.id,
                scheduledAt,
                patientName: visitor.name.trim(),
                patientPhone: visitor.phone.trim(),
                chiefComplaint: complaint,
                captchaToken,
            });
            setReference(result.reference);
            setStep('success');
        } catch {
            setError('Booking failed. Please try again.');
        } finally {
            setLoading(false);
        }
    };

    // Progress bar step count is dynamic: 5 dots if we need the branch step,
    // 4 otherwise. The current position is derived from the flow we're in.
    const flowSteps: Step[] = needsBranchStep
        ? ['branch', 'department', 'doctor', 'datetime', 'details']
        : ['department', 'doctor', 'datetime', 'details'];
    const currentStep = flowSteps.indexOf(step);

    return (
        <div>
            {step !== 'success' && (
                <div class="widget-steps">
                    {flowSteps.map((_, i) => (
                        <div key={i} class={`widget-step ${i < currentStep ? 'done' : i === currentStep ? 'active' : ''}`} />
                    ))}
                </div>
            )}

            {error && <div class="widget-error">{error}</div>}

            {step === 'branch' && (
                <div>
                    <div class="widget-section-title">Select Branch</div>
                    {doctorsLoading && branches.length === 0 && (
                        <div class="widget-section-sub">Loading…</div>
                    )}
                    {branches.map(branch => (
                        <button
                            key={branch}
                            class="widget-row-btn"
                            onClick={() => {
                                setSelectedBranch(branch);
                                setStep('department');
                            }}
                        >
                            <IconSpan class="widget-row-icon" name="hospital" size={20} />
                            <span class="widget-row-label">{branch}</span>
                            <IconSpan class="widget-row-chevron" name="arrow-right" size={14} />
                        </button>
                    ))}
                </div>
            )}

            {step === 'department' && (
                <div>
                    <div class="widget-section-title">
                        {selectedBranch && (
                            <>
                                <IconSpan class="widget-row-icon" name="hospital" size={16} />
                                {selectedBranch} —&nbsp;
                            </>
                        )}
                        Select Department
                    </div>
                    {doctorsLoading && departments.length === 0 && (
                        <div class="widget-section-sub">Loading…</div>
                    )}
                    {departments.map(dept => (
                        <button
                            key={dept}
                            class="widget-row-btn"
                            onClick={() => { setSelectedDept(dept); setStep('doctor'); }}
                        >
                            <IconSpan class="widget-row-icon" name={departmentIcon(dept)} size={20} />
                            <span class="widget-row-label">{dept.replace(/_/g, ' ')}</span>
                            <IconSpan class="widget-row-chevron" name="arrow-right" size={14} />
                        </button>
                    ))}
                    {branches.length > 1 && (
                        <button
                            class="widget-btn widget-btn-secondary widget-btn-with-icon"
                            style={{ marginTop: '8px' }}
                            onClick={() => setStep('branch')}
                        >
                            <IconSpan name="arrow-left" size={14} />
                            Change branch
                        </button>
                    )}
                </div>
            )}

            {step === 'doctor' && (
                <div>
                    <div class="widget-section-title">
                        <IconSpan class="widget-row-icon" name={departmentIcon(selectedDept)} size={16} />
                        {selectedDept.replace(/_/g, ' ')}
                    </div>
                    {filteredDoctors.map(doc => (
                        <button
                            key={doc.id}
                            class="widget-row-btn widget-row-btn-stack"
                            onClick={() => handleDoctorSelect(doc)}
                        >
                            <div class="widget-row-main">
                                <div class="widget-row-label">{doc.name}</div>
                                <div class="widget-row-sub">
                                    {doc.visitingHours ?? ''} {doc.clinic?.clinicName ? `• ${doc.clinic.clinicName}` : ''}
                                </div>
                            </div>
                            <IconSpan class="widget-row-chevron" name="arrow-right" size={14} />
                        </button>
                    ))}
                    <button class="widget-btn widget-btn-secondary widget-btn-with-icon" style={{ marginTop: '8px' }} onClick={() => setStep('department')}>
                        <IconSpan name="arrow-left" size={14} />
                        Back
                    </button>
                </div>
            )}

            {step === 'datetime' && (
                <div>
                    <div class="widget-section-title">{selectedDoctor?.name} — Pick Date & Time</div>
                    <div class="widget-field">
                        <label class="widget-label">Date</label>
                        <input
                            class="widget-input"
                            type="date"
                            value={selectedDate}
                            min={new Date().toISOString().split('T')[0]}
                            onInput={(e: any) => { setSelectedDate(e.target.value); setSelectedSlot(''); }}
                        />
                    </div>
                    {slots.length > 0 && (
                        <div>
                            <label class="widget-label">Available Slots</label>
                            <div class="widget-slots">
                                {slots.map(s => (
                                    <button
                                        key={s.time}
                                        class={`widget-slot ${s.time === selectedSlot ? 'selected' : ''} ${!s.available ? 'unavailable' : ''}`}
                                        onClick={() => s.available && setSelectedSlot(s.time)}
                                        disabled={!s.available}
                                    >
                                        {s.time}
                                    </button>
                                ))}
                            </div>
                        </div>
                    )}
                    <div class="widget-btn-row">
                        <button class="widget-btn widget-btn-secondary widget-btn-with-icon" onClick={() => setStep('doctor')}>
                            <IconSpan name="arrow-left" size={14} />
                            Back
                        </button>
                        <button class="widget-btn widget-btn-with-icon" disabled={!selectedSlot} onClick={() => setStep('details')}>
                            Next
                            <IconSpan name="arrow-right" size={14} color="#fff" />
                        </button>
                    </div>
                </div>
            )}

            {step === 'details' && (
                <div>
                    <div class="widget-section-title">Your Details</div>
                    <div class="widget-field">
                        <label class="widget-label">Full Name *</label>
                        <input
                            class="widget-input"
                            placeholder="Your name"
                            value={visitor.name}
                            onInput={(e: any) => updateVisitor({ name: e.target.value })}
                        />
                    </div>
                    <div class="widget-field">
                        <label class="widget-label">Phone Number *</label>
                        <input
                            class="widget-input"
                            placeholder="+91 9876543210"
                            value={visitor.phone}
                            onInput={(e: any) => updateVisitor({ phone: e.target.value })}
                        />
                    </div>
                    <div class="widget-field">
                        <label class="widget-label">Chief Complaint</label>
                        <textarea
                            class="widget-input widget-textarea"
                            placeholder="Describe your concern..."
                            value={complaint}
                            onInput={(e: any) => setComplaint(e.target.value)}
                        />
                    </div>
                    <div class="widget-btn-row">
                        <button class="widget-btn widget-btn-secondary widget-btn-with-icon" onClick={() => setStep('datetime')}>
                            <IconSpan name="arrow-left" size={14} />
                            Back
                        </button>
                        <button
                            class="widget-btn"
                            disabled={!visitor.name.trim() || !visitor.phone.trim() || loading}
                            onClick={handleBook}
                        >
                            {loading ? 'Booking...' : 'Book Appointment'}
                        </button>
                    </div>
                </div>
            )}

            {step === 'success' && (
                <div class="widget-success">
                    <div class="widget-success-icon">
                        <IconSpan name="circle-check" size={56} color="#059669" />
                    </div>
                    <div class="widget-success-title">Appointment Booked!</div>
                    <div class="widget-success-text">
                        Reference: <strong>{reference}</strong><br />
                        {selectedDoctor?.name} • {selectedDate} at {selectedSlot}<br /><br />
                        We'll send a confirmation SMS to your phone.
                    </div>
                </div>
            )}
        </div>
    );
};
