import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Button, Spinner } from '@wordpress/components';
import BookingStatusBadge from './BookingStatusBadge';
import OfferModal from './OfferModal';
import StatusChangeModal from './StatusChangeModal';
import api from '../api/client';

export default function BookingTable( {
    bookings,
    loading,
    page,
    perPage,
    total,
    onPageChange,
    onPerPageChange,
    onRefresh,
    navigate,
} ) {
    // Pro extension hook: Appointly Pro can inject extra cells/badges into
    // each booking row (e.g. "Recurring" badge, "X/Y seats" badge) by
    // populating window.appointlyAdmin.proBookingsListRowExtras with an array of
    // functions: Array<(booking) => JSX | null>.
    const proRowExtras = ( typeof window !== 'undefined' && window.appointlyAdmin?.proBookingsListRowExtras ) || [];

    const [ offerBooking, setOfferBooking ]   = useState( null );
    const [ actionLoading, setActionLoading ] = useState( null );
    const [ statusModal, setStatusModal ]     = useState( null );

    const totalPages = Math.ceil( total / perPage );

    const openConfirmFor = ( booking ) => {
        setStatusModal( {
            bookingId: booking.id,
            action: 'confirm',
            title: __( 'Mark as Accepted', 'appointly' ),
            description: __( 'Change the booking status to "confirmed". You can optionally send the customer a confirmation email and add a note.', 'appointly' ),
            confirmLabel: __( 'Mark as Accepted', 'appointly' ),
            confirmVariant: 'primary',
            defaultNotify: true,
        } );
    };

    const openDeclineFor = ( booking ) => {
        setStatusModal( {
            bookingId: booking.id,
            action: 'decline',
            title: __( 'Decline Booking', 'appointly' ),
            description: __( 'Change the booking status to "declined". You can optionally send the customer a polite rejection email and add a note.', 'appointly' ),
            confirmLabel: __( 'Decline', 'appointly' ),
            confirmVariant: 'secondary',
            confirmIsDestructive: true,
            defaultNotify: true,
        } );
    };

    const openCancelFor = ( booking ) => {
        setStatusModal( {
            bookingId: booking.id,
            action: 'cancel',
            title: booking.status === 'offered'
                ? __( 'Cancel Offer', 'appointly' )
                : __( 'Cancel Booking', 'appointly' ),
            description: booking.status === 'offered'
                ? __( 'Withdraw the offer you sent to the customer. You can optionally notify them by email.', 'appointly' )
                : __( 'Cancel this confirmed booking. You can optionally notify the customer by email.', 'appointly' ),
            confirmLabel: booking.status === 'offered'
                ? __( 'Cancel Offer', 'appointly' )
                : __( 'Cancel Booking', 'appointly' ),
            confirmVariant: 'secondary',
            confirmIsDestructive: true,
            defaultNotify: true,
        } );
    };

    const runStatusChange = async ( { notifyCustomer, adminNote } ) => {
        if ( ! statusModal ) return;
        const bookingId = statusModal.bookingId;
        setActionLoading( bookingId );
        try {
            const payload = { notify_customer: notifyCustomer };
            if ( adminNote ) {
                payload.admin_note = adminNote;
            }
            if ( statusModal.action === 'confirm' ) {
                await api.confirmBooking( bookingId, payload );
            } else if ( statusModal.action === 'decline' ) {
                await api.declineBooking( bookingId, payload );
            } else if ( statusModal.action === 'cancel' ) {
                await api.cancelBooking( bookingId, payload );
            }
            setStatusModal( null );
            onRefresh();
        } catch ( err ) {
            setStatusModal( null );
            window.alert( err?.message || __( 'Action failed.', 'appointly' ) );
        } finally {
            setActionLoading( null );
        }
    };

    const handleDelete = async ( id ) => {
        if ( ! window.confirm( __( 'Delete this booking permanently?', 'appointly' ) ) ) return;
        setActionLoading( id );
        try {
            await api.deleteBooking( id );
            onRefresh();
        } catch ( err ) {
            window.alert( err?.message || __( 'Failed to delete booking.', 'appointly' ) );
        } finally {
            setActionLoading( null );
        }
    };

    const handleOfferSuccess = () => {
        setOfferBooking( null );
        onRefresh();
    };

    if ( loading ) {
        return (
            <div className="appointly-table-loading">
                <Spinner />
            </div>
        );
    }

    if ( ! bookings || bookings.length === 0 ) {
        return (
            <div className="appointly-table-empty">
                <p>{ __( 'No bookings found.', 'appointly' ) }</p>
            </div>
        );
    }

    return (
        <>
            <div className="appointly-table-wrap">
                <table className="appointly-table">
                    <thead>
                        <tr>
                            <th>{ __( 'Date', 'appointly' ) }</th>
                            <th>{ __( 'Name', 'appointly' ) }</th>
                            <th>{ __( 'Service', 'appointly' ) }</th>
                            <th>{ __( 'Status', 'appointly' ) }</th>
                            <th>{ __( 'Price', 'appointly' ) }</th>
                            <th>{ __( 'Created', 'appointly' ) }</th>
                            { proRowExtras.length > 0 && (
                                <th className="appointly-table__col-extras"></th>
                            ) }
                            <th>{ __( 'Actions', 'appointly' ) }</th>
                        </tr>
                    </thead>
                    <tbody>
                        { bookings.map( ( booking ) => (
                            <tr
                                key={ booking.id }
                                className="appointly-table__row"
                                onClick={ () => navigate( `/bookings/${ booking.id }` ) }
                            >
                                <td>{ booking.booking_date }</td>
                                <td>{ booking.customer_name }</td>
                                <td>{ booking.service_name }</td>
                                <td>
                                    <BookingStatusBadge status={ booking.status } />
                                </td>
                                <td>
                                    { booking.price
                                        ? `€${ parseFloat( booking.price ).toFixed( 2 ) }`
                                        : '—' }
                                </td>
                                <td>{ booking.created_at }</td>
                                { proRowExtras.length > 0 && (
                                    <td className="appointly-admin__booking-row-extras">
                                        { proRowExtras.map( ( render, i ) => {
                                            try {
                                                const node = render( booking );
                                                return node ? <span key={ i }>{ node }</span> : null;
                                            } catch ( err ) {
                                                console.error( 'Pro row extras renderer threw:', err );
                                                return null;
                                            }
                                        } ) }
                                    </td>
                                ) }
                                <td
                                    onClick={ ( e ) => e.stopPropagation() }
                                    className="appointly-table__actions"
                                >
                                    { actionLoading === booking.id ? (
                                        <Spinner />
                                    ) : (
                                        <>
                                            { booking.status === 'pending' && (
                                                <>
                                                    <Button
                                                        variant="primary"
                                                        size="small"
                                                        onClick={ () => setOfferBooking( booking ) }
                                                        title={ __( 'Open the offer modal to send the customer a priced offer email.', 'appointly' ) }
                                                    >
                                                        { __( 'Send Offer', 'appointly' ) }
                                                    </Button>
                                                    <Button
                                                        variant="primary"
                                                        size="small"
                                                        onClick={ () => openConfirmFor( booking ) }
                                                        title={ __( 'Skip the offer step and mark this booking as confirmed.', 'appointly' ) }
                                                    >
                                                        { __( 'Accept', 'appointly' ) }
                                                    </Button>
                                                    <Button
                                                        variant="secondary"
                                                        size="small"
                                                        isDestructive
                                                        onClick={ () => openDeclineFor( booking ) }
                                                        title={ __( 'Politely decline this request.', 'appointly' ) }
                                                    >
                                                        { __( 'Decline', 'appointly' ) }
                                                    </Button>
                                                    <Button
                                                        variant="tertiary"
                                                        size="small"
                                                        isDestructive
                                                        onClick={ () => handleDelete( booking.id ) }
                                                        title={ __( 'Permanently delete this booking row. There is no undo. Use for spam or test data.', 'appointly' ) }
                                                    >
                                                        { __( 'Delete', 'appointly' ) }
                                                    </Button>
                                                </>
                                            ) }

                                            { booking.status === 'offered' && (
                                                <Button
                                                    variant="secondary"
                                                    size="small"
                                                    isDestructive
                                                    onClick={ () => openCancelFor( booking ) }
                                                    title={ __( 'Withdraw the offer you sent to the customer.', 'appointly' ) }
                                                >
                                                    { __( 'Cancel Offer', 'appointly' ) }
                                                </Button>
                                            ) }

                                            { booking.status === 'confirmed' && (
                                                <Button
                                                    variant="secondary"
                                                    size="small"
                                                    isDestructive
                                                    onClick={ () => openCancelFor( booking ) }
                                                    title={ __( 'Cancel this confirmed booking.', 'appointly' ) }
                                                >
                                                    { __( 'Cancel Booking', 'appointly' ) }
                                                </Button>
                                            ) }

                                            { ( booking.status === 'declined' || booking.status === 'cancelled' ) && (
                                                <Button
                                                    variant="tertiary"
                                                    size="small"
                                                    isDestructive
                                                    onClick={ () => handleDelete( booking.id ) }
                                                    title={ __( 'Permanently delete this row. Use for cleanup of finalized records.', 'appointly' ) }
                                                >
                                                    { __( 'Delete', 'appointly' ) }
                                                </Button>
                                            ) }
                                        </>
                                    ) }
                                </td>
                            </tr>
                        ) ) }
                    </tbody>
                </table>
            </div>

            { /* Pagination */ }
            <div className="appointly-pagination">
                <div className="appointly-pagination__info">
                    { total }{ ' ' }{ __( 'bookings total', 'appointly' ) }
                </div>
                <div className="appointly-pagination__controls">
                    <select
                        value={ perPage }
                        onChange={ ( e ) => onPerPageChange( Number( e.target.value ) ) }
                        className="appointly-pagination__per-page"
                    >
                        { [ 10, 25, 50, 100 ].map( ( n ) => (
                            <option key={ n } value={ n }>
                                { n } { __( 'per page', 'appointly' ) }
                            </option>
                        ) ) }
                    </select>
                    <div className="appointly-pagination__pages">
                        <Button
                            variant="secondary"
                            size="small"
                            disabled={ page <= 1 }
                            onClick={ () => onPageChange( page - 1 ) }
                        >
                            &laquo;
                        </Button>
                        { Array.from( { length: totalPages }, ( _, i ) => i + 1 )
                            .filter( ( p ) => {
                                // Show first, last, and nearby pages
                                return p === 1 || p === totalPages || Math.abs( p - page ) <= 2;
                            } )
                            .reduce( ( acc, p, idx, arr ) => {
                                if ( idx > 0 && p - arr[ idx - 1 ] > 1 ) {
                                    acc.push( <span key={ `ellipsis-${ p }` } className="appointly-pagination__ellipsis">&hellip;</span> );
                                }
                                acc.push(
                                    <Button
                                        key={ p }
                                        variant={ p === page ? 'primary' : 'secondary' }
                                        size="small"
                                        onClick={ () => onPageChange( p ) }
                                    >
                                        { p }
                                    </Button>
                                );
                                return acc;
                            }, [] ) }
                        <Button
                            variant="secondary"
                            size="small"
                            disabled={ page >= totalPages }
                            onClick={ () => onPageChange( page + 1 ) }
                        >
                            &raquo;
                        </Button>
                    </div>
                </div>
            </div>

            { /* Offer Modal */ }
            { offerBooking && (
                <OfferModal
                    booking={ offerBooking }
                    onClose={ () => setOfferBooking( null ) }
                    onSuccess={ handleOfferSuccess }
                />
            ) }

            { /* Status change confirmation modal */ }
            { statusModal && (
                <StatusChangeModal
                    title={ statusModal.title }
                    description={ statusModal.description }
                    confirmLabel={ statusModal.confirmLabel }
                    confirmVariant={ statusModal.confirmVariant }
                    confirmIsDestructive={ !! statusModal.confirmIsDestructive }
                    defaultNotify={ statusModal.defaultNotify }
                    busy={ !! actionLoading }
                    onConfirm={ runStatusChange }
                    onCancel={ () => setStatusModal( null ) }
                />
            ) }
        </>
    );
}
