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

export default function BookingDetail( { id, navigate } ) {
    const [ booking, setBooking ]           = useState( null );
    const [ loading, setLoading ]           = useState( true );
    const [ error, setError ]               = useState( null );
    const [ showOfferModal, setShowOfferModal ] = useState( false );
    const [ actionLoading, setActionLoading ]   = useState( false );
    const [ statusModal, setStatusModal ]       = useState( null );

    // Pro extension hook: Appointly Pro can inject extra booking detail
    // sections (e.g. recurring-bookings info) by populating
    // window.appointlyAdmin.proBookingDetailSections with an array of
    // { key, label, component } objects.
    const proBookingDetailSections = ( typeof window !== 'undefined' && window.appointlyAdmin?.proBookingDetailSections ) || [];

    const fetchBooking = useCallback( async () => {
        setLoading( true );
        setError( null );
        try {
            const data = await api.getBooking( id );
            setBooking( data?.booking || data );
        } catch ( err ) {
            setError( err?.message || __( 'Failed to load booking.', 'appointly' ) );
        } finally {
            setLoading( false );
        }
    }, [ id ] );

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

    const handleOfferSuccess = () => {
        setShowOfferModal( false );
        fetchBooking();
    };

    const openConfirmModal = () => {
        setStatusModal( {
            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 openDeclineModal = () => {
        setStatusModal( {
            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 openCancelModal = () => {
        setStatusModal( {
            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;
        setActionLoading( true );
        try {
            const payload = { notify_customer: notifyCustomer };
            if ( adminNote ) {
                payload.admin_note = adminNote;
            }
            if ( statusModal.action === 'confirm' ) {
                await api.confirmBooking( id, payload );
            } else if ( statusModal.action === 'decline' ) {
                await api.declineBooking( id, payload );
            } else if ( statusModal.action === 'cancel' ) {
                await api.cancelBooking( id, payload );
            }
            setStatusModal( null );
            fetchBooking();
        } catch ( err ) {
            setStatusModal( null );
            window.alert( err?.message || __( 'Action failed. Please try again.', 'appointly' ) );
        } finally {
            setActionLoading( false );
        }
    };

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

    if ( error ) {
        return (
            <div className="appointly-detail-error">
                <Notice status="error" isDismissible={ false }>{ error }</Notice>
                <Button variant="secondary" onClick={ () => navigate( '/bookings' ) }>
                    { __( 'Back to Bookings', 'appointly' ) }
                </Button>
            </div>
        );
    }

    if ( ! booking ) return null;

    // Parse custom fields
    let customFields = {};
    if ( booking.custom_fields ) {
        try {
            customFields = typeof booking.custom_fields === 'string'
                ? JSON.parse( booking.custom_fields )
                : booking.custom_fields;
        } catch ( e ) {
            customFields = {};
        }
    }

    // Parse custom_fields_meta (from Patch 1a: enriches the REST response).
    const customFieldsMeta = Array.isArray( booking.custom_fields_meta )
        ? booking.custom_fields_meta
        : [];

    // Build a quick lookup by key for O(1) access during render.
    const metaByKey = customFieldsMeta.reduce( ( acc, m ) => {
        acc[ m.key ] = m;
        return acc;
    }, {} );

    // Format a custom field value based on its declared type.
    const formatCustomFieldValue = ( value, fieldType ) => {
        if ( value === null || value === undefined || value === '' ) {
            return '—';
        }
        switch ( fieldType ) {
            case 'checkbox':
                // Free's appointly-calendar.js normalises checkbox values to '1' / '0'.
                return String( value ) === '1'
                    ? __( 'Yes', 'appointly' )
                    : __( 'No', 'appointly' );
            case 'number': {
                const num = Number( value );
                if ( Number.isNaN( num ) ) return String( value );
                return num.toLocaleString();
            }
            case 'textarea':
                // Return as-is; the rendering uses CSS white-space: pre-wrap.
                return String( value );
            case 'text':
            case 'select':
            default:
                return String( value );
        }
    };

    // Timeline events
    const timeline = [];
    if ( booking.created_at ) {
        timeline.push( { label: __( 'Created', 'appointly' ), time: booking.created_at } );
    }
    if ( booking.offered_at ) {
        timeline.push( { label: __( 'Offer Sent', 'appointly' ), time: booking.offered_at } );
    }
    if ( booking.confirmed_at ) {
        timeline.push( { label: __( 'Confirmed', 'appointly' ), time: booking.confirmed_at } );
    }
    if ( booking.declined_at ) {
        timeline.push( { label: __( 'Declined', 'appointly' ), time: booking.declined_at } );
    }
    if ( booking.cancelled_at ) {
        timeline.push( { label: __( 'Cancelled', 'appointly' ), time: booking.cancelled_at } );
    }

    const addons = booking.addon_selections || [];

    return (
        <div className="appointly-detail">
            <div className="appointly-detail__back">
                <Button variant="tertiary" onClick={ () => navigate( '/bookings' ) }>
                    &larr; { __( 'Back to Bookings', 'appointly' ) }
                </Button>
            </div>

            <div className="appointly-detail__layout">
                { /* Left Column */ }
                <div className="appointly-detail__main">
                    { /* Customer Info */ }
                    <div className="appointly-card">
                        <h3>{ __( 'Customer Information', 'appointly' ) }</h3>
                        <div className="appointly-card__grid">
                            <div className="appointly-card__field">
                                <span className="appointly-card__label">{ __( 'Name', 'appointly' ) }</span>
                                <span className="appointly-card__value">{ booking.customer_name }</span>
                            </div>
                            <div className="appointly-card__field">
                                <span className="appointly-card__label">{ __( 'Email', 'appointly' ) }</span>
                                <span className="appointly-card__value">
                                    <a href={ `mailto:${ booking.customer_email }` }>
                                        { booking.customer_email }
                                    </a>
                                </span>
                            </div>
                            { booking.customer_phone && (
                                <div className="appointly-card__field">
                                    <span className="appointly-card__label">{ __( 'Phone', 'appointly' ) }</span>
                                    <span className="appointly-card__value">{ booking.customer_phone }</span>
                                </div>
                            ) }
                            { booking.message && (
                                <div className="appointly-card__field appointly-card__field--full">
                                    <span className="appointly-card__label">{ __( 'Message', 'appointly' ) }</span>
                                    <span className="appointly-card__value">{ booking.message }</span>
                                </div>
                            ) }
                        </div>
                    </div>

                    { /* Custom Fields */ }
                    { Object.keys( customFields ).length > 0 && (
                        <div className="appointly-card">
                            <h3>{ __( 'Custom Fields', 'appointly' ) }</h3>
                            <div className="appointly-card__grid">
                                { Object.entries( customFields ).map( ( [ key, value ] ) => {
                                    const meta = metaByKey[ key ] || {
                                        label: key,
                                        field_type: 'text',
                                    };
                                    const formatted = formatCustomFieldValue( value, meta.field_type );
                                    const valueClassName = meta.field_type === 'textarea'
                                        ? 'appointly-card__value appointly-card__value--pre'
                                        : 'appointly-card__value';
                                    return (
                                        <div key={ key } className="appointly-card__field">
                                            <span className="appointly-card__label">{ meta.label }</span>
                                            <span className={ valueClassName }>{ formatted }</span>
                                        </div>
                                    );
                                } ) }
                            </div>
                        </div>
                    ) }

                    { /* Booking Details */ }
                    <div className="appointly-card">
                        <h3>{ __( 'Booking Details', 'appointly' ) }</h3>
                        <div className="appointly-card__grid">
                            <div className="appointly-card__field">
                                <span className="appointly-card__label">{ __( 'Service', 'appointly' ) }</span>
                                <span className="appointly-card__value">{ booking.service_name }</span>
                            </div>
                            <div className="appointly-card__field">
                                <span className="appointly-card__label">{ __( 'Date', 'appointly' ) }</span>
                                <span className="appointly-card__value">
                                    { booking.is_range
                                        ? booking.booking_date + ' \u2014 ' + booking.booking_date_end
                                        : booking.booking_date }
                                </span>
                            </div>
                            { booking.time_slot && (
                                <div className="appointly-card__field">
                                    <span className="appointly-card__label">{ __( 'Time Slot', 'appointly' ) }</span>
                                    <span className="appointly-card__value">{ booking.time_slot }</span>
                                </div>
                            ) }
                        </div>
                    </div>

                    { /* Addons */ }
                    { addons.length > 0 && (
                        <div className="appointly-card">
                            <h3>{ __( 'Addons', 'appointly' ) }</h3>
                            <table className="appointly-table appointly-table--compact">
                                <thead>
                                    <tr>
                                        <th>{ __( 'Addon', 'appointly' ) }</th>
                                        <th>{ __( 'Quantity', 'appointly' ) }</th>
                                        <th>{ __( 'Price', 'appointly' ) }</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    { addons.map( ( addon, idx ) => (
                                        <tr key={ idx }>
                                            <td>{ addon.name }</td>
                                            <td>{ addon.quantity || 1 }</td>
                                            <td>
                                                { addon.price
                                                    ? `€${ parseFloat( addon.price ).toFixed( 2 ) }`
                                                    : '—' }
                                            </td>
                                        </tr>
                                    ) ) }
                                </tbody>
                            </table>
                        </div>
                    ) }
                </div>

                { /* Right Column */ }
                <div className="appointly-detail__sidebar">
                    { /* Status Card */ }
                    <div className="appointly-card">
                        <h3>{ __( 'Status', 'appointly' ) }</h3>
                        <div className="appointly-detail__status-display">
                            <BookingStatusBadge status={ booking.status } large />
                        </div>
                        { booking.price && (
                            <div className="appointly-detail__price">
                                <span className="appointly-card__label">{ __( 'Price', 'appointly' ) }</span>
                                <span className="appointly-detail__price-value">
                                    €{ parseFloat( booking.price ).toFixed( 2 ) }
                                </span>
                            </div>
                        ) }
                        { booking.admin_note && (
                            <div className="appointly-detail__note">
                                <span className="appointly-card__label">{ __( 'Admin Note', 'appointly' ) }</span>
                                <p>{ booking.admin_note }</p>
                            </div>
                        ) }
                    </div>

                    { /* Timeline */ }
                    { timeline.length > 0 && (
                        <div className="appointly-card">
                            <h3>{ __( 'Timeline', 'appointly' ) }</h3>
                            <div className="appointly-timeline">
                                { timeline.map( ( event, idx ) => (
                                    <div key={ idx } className="appointly-timeline__event">
                                        <div className="appointly-timeline__dot" />
                                        <div className="appointly-timeline__content">
                                            <strong>{ event.label }</strong>
                                            <span>{ event.time }</span>
                                        </div>
                                    </div>
                                ) ) }
                            </div>
                        </div>
                    ) }

                    { /* Actions */ }
                    { ( booking.status === 'pending' || booking.status === 'offered' || booking.status === 'confirmed' ) && (
                        <div className="appointly-card">
                            <h3>{ __( 'Actions', 'appointly' ) }</h3>
                            <div className="appointly-detail__actions">
                                { booking.status === 'pending' && (
                                    <>
                                        <Button
                                            variant="primary"
                                            onClick={ () => setShowOfferModal( true ) }
                                            disabled={ actionLoading }
                                            title={ __( 'Open the offer modal to send the customer a priced offer email.', 'appointly' ) }
                                        >
                                            { __( 'Send Offer', 'appointly' ) }
                                        </Button>
                                        <Button
                                            variant="primary"
                                            onClick={ openConfirmModal }
                                            disabled={ actionLoading }
                                            title={ __( 'Skip the offer step and mark this booking as confirmed. Useful when you already agreed with the customer offline.', 'appointly' ) }
                                        >
                                            { __( 'Mark as Accepted', 'appointly' ) }
                                        </Button>
                                        <Button
                                            variant="secondary"
                                            isDestructive
                                            onClick={ openDeclineModal }
                                            disabled={ actionLoading }
                                            title={ __( 'Politely decline this request. The customer can be informed by email.', 'appointly' ) }
                                        >
                                            { __( 'Decline', 'appointly' ) }
                                        </Button>
                                    </>
                                ) }

                                { booking.status === 'offered' && (
                                    <>
                                        <Button
                                            variant="primary"
                                            onClick={ openConfirmModal }
                                            disabled={ actionLoading }
                                            title={ __( 'Mark this offer as accepted (e.g., the customer confirmed offline).', 'appointly' ) }
                                        >
                                            { __( 'Mark as Accepted', 'appointly' ) }
                                        </Button>
                                        <Button
                                            variant="secondary"
                                            onClick={ openDeclineModal }
                                            disabled={ actionLoading }
                                            title={ __( 'Mark this offer as declined (e.g., the customer declined offline).', 'appointly' ) }
                                        >
                                            { __( 'Mark as Declined', 'appointly' ) }
                                        </Button>
                                        <Button
                                            variant="secondary"
                                            isDestructive
                                            onClick={ openCancelModal }
                                            disabled={ actionLoading }
                                            title={ __( 'Withdraw the offer you sent. The customer can be notified by email.', 'appointly' ) }
                                        >
                                            { __( 'Cancel Offer', 'appointly' ) }
                                        </Button>
                                    </>
                                ) }

                                { booking.status === 'confirmed' && (
                                    <Button
                                        variant="secondary"
                                        isDestructive
                                        onClick={ openCancelModal }
                                        disabled={ actionLoading }
                                        title={ __( 'Cancel this confirmed booking. The customer can be notified by email.', 'appointly' ) }
                                    >
                                        { __( 'Cancel Booking', 'appointly' ) }
                                    </Button>
                                ) }

                                { actionLoading && <Spinner /> }
                            </div>
                        </div>
                    ) }

                    { 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 ) }
                        />
                    ) }
                </div>
            </div>

            { /* Pro extension sections — rendered only if Appointly Pro is active. */ }
            { proBookingDetailSections.map( ( section ) => {
                const SectionComponent = section.component;
                if ( ! SectionComponent ) return null;
                return (
                    <div key={ section.key } className="appointly-card appointly-card--pro">
                        <h3>
                            { section.label }
                            <span className="appointly-editor-section__pro-badge">{ __( 'Pro', 'appointly' ) }</span>
                        </h3>
                        <SectionComponent booking={ booking } service={ null } onUpdate={ fetchBooking } />
                    </div>
                );
            } ) }

            { /* Offer Modal */ }
            { showOfferModal && (
                <OfferModal
                    booking={ booking }
                    onClose={ () => setShowOfferModal( false ) }
                    onSuccess={ handleOfferSuccess }
                />
            ) }
        </div>
    );
}
