import { useState, useEffect, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import {
    Button,
    Spinner,
    Notice,
    TextControl,
    TextareaControl,
    ToggleControl,
} from '@wordpress/components';
import api from '../api/client';

/**
 * Service editor — Free version.
 *
 * The Free plugin supports a simple service with title, description,
 * image, minimum lead days, and base price. Day-mode booking only.
 *
 * Appointly Pro (the separate companion plugin) extends this editor
 * via the `window.appointlyAdmin.proServiceEditorExtras` global to add:
 * - booking-mode selector (Day vs Timeslot)
 * - slot configurator (start, end, duration)
 * - custom field builder
 * - service addons (upsells)
 *
 * When Pro is not installed, the editor renders in its simple form.
 */

const DEFAULT_SERVICE = {
    title: '',
    description: '',
    image_url: '',
    image_id: 0,
    is_active: true,
    min_lead_days: 1,
    base_price: '',
};

export default function ServiceEditor({ id, navigate }) {
    const isNew = !id || id === 'new';

    const [service, setService] = useState({ ...DEFAULT_SERVICE });
    const [loading, setLoading] = useState(!isNew);
    const [saving, setSaving] = useState(false);
    const [error, setError] = useState(null);
    const [success, setSuccess] = useState(null);

    // Pro extension hook: Appointly Pro can inject extra service editor
    // sections (slot configurator, field builder, addon editor) by
    // populating window.appointlyAdmin.proServiceEditorExtras with an array of
    // { key, label, component } objects.
    const proExtras = window.appointlyAdmin?.proServiceEditorExtras || [];

    // Load existing service.
    const fetchService = useCallback(async () => {
        if (isNew) return;
        setLoading(true);
        setError(null);
        try {
            const svcRes = await api.getService(id);
            const svc = svcRes?.service || svcRes;
            setService({
                ...svc,
                title: svc.title || '',
                description: svc.description || '',
                image_url: svc.image_url || '',
                image_id: svc.image_id || 0,
                is_active: svc.status === 'active' || svc.is_active !== false,
                min_lead_days: svc.min_lead_days ?? 3,
                base_price: svc.base_price ?? '',
            });
        } catch (err) {
            setError(err?.message || __('Failed to load service.', 'appointly'));
        } finally {
            setLoading(false);
        }
    }, [id, isNew]);

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

    const updateField = (key, value) => {
        setService((prev) => ({ ...prev, [key]: value }));
    };

    const openMediaLibrary = () => {
        if (!window.wp || !window.wp.media) {
            window.alert(__('WordPress Media Library is not available.', 'appointly'));
            return;
        }

        const frame = window.wp.media({
            title: __('Select Service Image', 'appointly'),
            button: { text: __('Use this image', 'appointly') },
            multiple: false,
            library: { type: 'image' },
        });

        frame.on('select', () => {
            const attachment = frame.state().get('selection').first().toJSON();
            updateField('image_url', attachment.url);
            updateField('image_id', attachment.id);
        });

        frame.open();
    };

    const removeImage = () => {
        updateField('image_url', '');
        updateField('image_id', 0);
    };

    const handleSave = async () => {
        if (!service.title.trim()) {
            setError(__('Service title is required.', 'appointly'));
            return;
        }

        setSaving(true);
        setError(null);
        setSuccess(null);

        try {
            let serviceId = id;

            const payload = {
                title: service.title.trim(),
                description: service.description.trim(),
                image_id: service.image_id || null,
                status: service.is_active ? 'active' : 'inactive',
                booking_mode: 'day',
                min_lead_days: parseInt(service.min_lead_days, 10) || 3,
                base_price: service.base_price !== '' ? parseFloat(service.base_price) || 0 : null,
            };

            // Pro extras hook: allow Pro to add its own fields to the save
            // payload before it hits the REST endpoint.
            const proPayloadFilter = window.appointlyAdmin?.proServiceEditorPayload;
            const finalPayload = typeof proPayloadFilter === 'function'
                ? proPayloadFilter(payload, service)
                : payload;

            if (isNew) {
                const result = await api.createService(finalPayload);
                serviceId = result?.service?.id || result?.id;
            } else {
                await api.updateService(id, finalPayload);
            }

            setSuccess(__('Service saved successfully.', 'appointly'));

            if (isNew && serviceId) {
                navigate(`/services/${serviceId}`);
            }
        } catch (err) {
            setError(err?.message || __('Failed to save service.', 'appointly'));
        } finally {
            setSaving(false);
        }
    };

    if (loading) {
        return (
            <div className="appointly-editor-loading">
                <Spinner />
                <p>{__('Loading service…', 'appointly')}</p>
            </div>
        );
    }

    return (
        <div className="appointly-service-editor">
            <div className="appointly-service-editor__top-bar">
                <Button variant="tertiary" onClick={() => navigate('/services')}>
                    &larr; {__('Back to Services', 'appointly')}
                </Button>
                <h2>
                    {isNew
                        ? __('New Service', 'appointly')
                        : __('Edit Service', 'appointly')}
                </h2>
            </div>

            {error && (
                <Notice status="error" isDismissible onDismiss={() => setError(null)}>
                    {error}
                </Notice>
            )}
            {success && (
                <Notice status="success" isDismissible onDismiss={() => setSuccess(null)}>
                    {success}
                </Notice>
            )}

            {/* Section 1: Basics */}
            <div className="appointly-editor-section">
                <h3 className="appointly-editor-section__title">
                    {__('Basics', 'appointly')}
                </h3>
                <div className="appointly-editor-section__body">
                    <TextControl
                        label={__('Title', 'appointly')}
                        value={service.title}
                        onChange={(val) => updateField('title', val)}
                        placeholder={__('e.g. Portrait Session', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <TextareaControl
                        label={__('Description', 'appointly')}
                        value={service.description}
                        onChange={(val) => updateField('description', val)}
                        rows={3}
                        __nextHasNoMarginBottom={ true }
                    />

                    <div className="appointly-editor-image">
                        <label className="appointly-editor-image__label">
                            {__('Image', 'appointly')}
                        </label>
                        {service.image_url ? (
                            <div className="appointly-editor-image__preview">
                                <img src={service.image_url} alt={service.title} />
                                <div className="appointly-editor-image__actions">
                                    <Button variant="secondary" size="small" onClick={openMediaLibrary}>
                                        {__('Replace', 'appointly')}
                                    </Button>
                                    <Button
                                        variant="tertiary"
                                        isDestructive
                                        size="small"
                                        onClick={removeImage}
                                    >
                                        {__('Remove', 'appointly')}
                                    </Button>
                                </div>
                            </div>
                        ) : (
                            <Button variant="secondary" onClick={openMediaLibrary}>
                                {__('Select Image', 'appointly')}
                            </Button>
                        )}
                    </div>

                    <ToggleControl
                        label={__('Active', 'appointly')}
                        checked={service.is_active}
                        onChange={(val) => updateField('is_active', val)}
                        help={service.is_active
                            ? __('Service is visible to customers.', 'appointly')
                            : __('Service is hidden from customers.', 'appointly')}
                            __nextHasNoMarginBottom={ true }
                    />
                </div>
            </div>

            {/* Section 2: Availability & Pricing */}
            <div className="appointly-editor-section">
                <h3 className="appointly-editor-section__title">
                    {__('Availability & Pricing', 'appointly')}
                </h3>
                <div className="appointly-editor-section__body">
                    <TextControl
                        label={__('Minimum Lead Days', 'appointly')}
                        type="number"
                        min="0"
                        value={service.min_lead_days}
                        onChange={(val) => updateField('min_lead_days', val)}
                        help={__('How many days in advance must a booking be made.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />

                    <TextControl
                        label={__('Base Price', 'appointly')}
                        type="number"
                        step="0.01"
                        min="0"
                        value={service.base_price}
                        onChange={(val) => updateField('base_price', val)}
                        help={__('Base price for this service. Leave empty for no default price.', 'appointly')}
                        placeholder="0.00"
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                </div>
            </div>

            {/* Pro extension sections — rendered only if Appointly Pro is active. */}
            {proExtras.map((extra) => {
                const Extra = extra.component;
                if (!Extra) return null;
                return (
                    <div key={extra.key} className="appointly-editor-section appointly-editor-section--pro">
                        <h3 className="appointly-editor-section__title">
                            {extra.label}
                            <span className="appointly-editor-section__pro-badge">{__('Pro', 'appointly')}</span>
                        </h3>
                        <div className="appointly-editor-section__body">
                            <Extra service={service} serviceId={id} onChange={setService} />
                        </div>
                    </div>
                );
            })}

            {/* Save/Cancel */}
            <div className="appointly-editor-actions">
                <Button
                    variant="primary"
                    onClick={handleSave}
                    disabled={saving}
                    isBusy={saving}
                >
                    {saving ? __('Saving…', 'appointly') : __('Save Service', 'appointly')}
                </Button>
                <Button
                    variant="tertiary"
                    onClick={() => navigate('/services')}
                    disabled={saving}
                >
                    {__('Cancel', 'appointly')}
                </Button>
            </div>
        </div>
    );
}
