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

/**
 * Collapsible panel component for settings sections.
 */
const SettingsPanel = ({ title, icon, defaultOpen = false, children }) => {
    const [isOpen, setIsOpen] = useState(defaultOpen);

    return (
        <div className={`appointly-settings-panel ${isOpen ? 'is-open' : ''}`}>
            <button
                type="button"
                className="appointly-settings-panel__header"
                onClick={() => setIsOpen(!isOpen)}
                aria-expanded={isOpen}
            >
                <span className="appointly-settings-panel__title">
                    <span className={`dashicons dashicons-${icon}`}></span>
                    {title}
                </span>
                <span className={`dashicons dashicons-arrow-${isOpen ? 'up' : 'down'}-alt2`}></span>
            </button>
            {isOpen && (
                <div className="appointly-settings-panel__body">
                    {children}
                </div>
            )}
        </div>
    );
};

/**
 * Frontend texts key-value editor.
 */
const FrontendTextsEditor = ({ texts, onChange }) => {
    const entries = Object.entries(texts || {});

    const handleValueChange = (key, value) => {
        onChange({ ...texts, [key]: value });
    };

    const handleAddRow = () => {
        const key = window.prompt(__('Enter string key:', 'appointly'));
        if (key && key.trim()) {
            onChange({ ...texts, [key.trim()]: '' });
        }
    };

    const handleRemoveRow = (key) => {
        const updated = { ...texts };
        delete updated[key];
        onChange(updated);
    };

    return (
        <div className="appointly-frontend-texts">
            {entries.length === 0 ? (
                <p className="appointly-frontend-texts__empty">
                    {__('No text overrides configured.', 'appointly')}
                </p>
            ) : (
                <div className="appointly-frontend-texts__list">
                    <div className="appointly-frontend-texts__row appointly-frontend-texts__row--header">
                        <span>{__('String Key', 'appointly')}</span>
                        <span>{__('Override Value', 'appointly')}</span>
                        <span></span>
                    </div>
                    {entries.map(([key, value]) => (
                        <div key={key} className="appointly-frontend-texts__row">
                            <code className="appointly-frontend-texts__key">{key}</code>
                            <TextControl
                                value={value}
                                onChange={(val) => handleValueChange(key, val)}
                                placeholder={__('(default)', 'appointly')}
                                className="appointly-frontend-texts__value"
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <Button
                                variant="tertiary"
                                isDestructive
                                icon="trash"
                                onClick={() => handleRemoveRow(key)}
                                label={__('Remove', 'appointly')}
                            />
                        </div>
                    ))}
                </div>
            )}
            <Button
                variant="secondary"
                onClick={handleAddRow}
                className="appointly-frontend-texts__add"
            >
                {__('Add Override', 'appointly')}
            </Button>
        </div>
    );
};

/**
 * Settings page - plugin configuration.
 *
 * Appointly Pro (the separate companion plugin) can inject additional settings
 * panels by populating window.appointlyAdmin.proSettingsPanels with an array of
 * { key, label, component } objects before this script evaluates.
 * Each component receives { settings, onChange } props.
 */
export default function Settings() {
    // Pro extension hook: Appointly Pro can inject extra settings panels
    // (e.g. Reminders lead-hours slider) by populating
    // window.appointlyAdmin.proSettingsPanels with an array of
    // { key, label, component } objects.
    const proSettingsPanels = window.appointlyAdmin?.proSettingsPanels || [];

    const [settings, setSettings]       = useState({});
    const [loading, setLoading]         = useState(true);
    const [saving, setSaving]           = useState(false);
    const [testingSmtp, setTestingSmtp] = useState(false);
    const [notice, setNotice]           = useState(null);
    const [copiedField, setCopiedField] = useState(null);

    /**
     * Load all settings.
     */
    const loadSettings = useCallback(async () => {
        setLoading(true);
        try {
            const data = await api.getSettings();
            setSettings(data?.settings || data || {});
        } catch {
            setNotice({ type: 'error', message: __('Failed to load settings.', 'appointly') });
        } finally {
            setLoading(false);
        }
    }, []);

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

    /**
     * Update a single settings key.
     */
    const updateField = (key, value) => {
        setSettings((prev) => ({ ...prev, [key]: value }));
    };

    /**
     * Save settings.
     */
    const handleSave = async () => {
        setSaving(true);
        setNotice(null);
        try {
            await api.updateSettings(settings);
            setNotice({ type: 'success', message: __('Settings saved.', 'appointly') });
        } catch {
            setNotice({ type: 'error', message: __('Failed to save settings.', 'appointly') });
        } finally {
            setSaving(false);
        }
    };

    /**
     * Test SMTP connection.
     */
    const handleTestSmtp = async () => {
        setTestingSmtp(true);
        setNotice(null);
        try {
            // Save current SMTP settings first, then test
            await api.updateSettings(settings);
            const res = await api.testSmtp();
            if (res.success) {
                setNotice({ type: 'success', message: __('SMTP connection successful! Test email sent.', 'appointly') });
            } else {
                setNotice({ type: 'error', message: res.message || __('SMTP connection failed.', 'appointly') });
            }
        } catch (err) {
            setNotice({
                type: 'error',
                message: err.message || __('SMTP connection test failed.', 'appointly'),
            });
        } finally {
            setTestingSmtp(false);
        }
    };

    /**
     * Copy text to clipboard.
     */
    const copyToClipboard = (text, fieldName) => {
        navigator.clipboard.writeText(text).then(() => {
            setCopiedField(fieldName);
            setTimeout(() => setCopiedField(null), 2000);
        });
    };

    /**
     * Reset all frontend text overrides.
     */
    const handleResetTexts = () => {
        // eslint-disable-next-line no-alert
        if (window.confirm(__('Reset all frontend text overrides to defaults?', 'appointly'))) {
            updateField('text_overrides', {});
        }
    };

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

    return (
        <div className="appointly-settings">
            <div className="appointly-settings__header">
                <h2>{__('Settings', 'appointly')}</h2>
            </div>

            {notice && (
                <Notice
                    status={notice.type}
                    isDismissible
                    onDismiss={() => setNotice(null)}
                    className="appointly-settings__notice"
                >
                    {notice.message}
                </Notice>
            )}

            {/* General */}
            <SettingsPanel
                title={__('General', 'appointly')}
                icon="admin-generic"
                defaultOpen={true}
            >
                <div className="appointly-settings__fields">
                    <TextControl
                        label={__('Admin Email', 'appointly')}
                        value={settings.admin_email || ''}
                        onChange={(val) => updateField('admin_email', val)}
                        type="email"
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <SelectControl
                        label={__('Date Format', 'appointly')}
                        value={settings.date_format || 'd.m.Y'}
                        options={[
                            { value: 'd.m.Y', label: 'd.m.Y (31.12.2026)' },
                            { value: 'm/d/Y', label: 'm/d/Y (12/31/2026)' },
                            { value: 'Y-m-d', label: 'Y-m-d (2026-12-31)' },
                        ]}
                        onChange={(val) => updateField('date_format', val)}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <TextControl
                        label={__('Currency', 'appointly')}
                        value={settings.currency || 'EUR'}
                        onChange={(val) => updateField('currency', val)}
                        help={__('ISO 4217 currency code (e.g., EUR, USD, GBP).', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <TextControl
                        label={__('Currency Symbol', 'appointly')}
                        value={settings.currency_symbol || '\u20AC'}
                        onChange={(val) => updateField('currency_symbol', val)}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <SelectControl
                        label={__('Currency Position', 'appointly')}
                        value={settings.currency_position || 'after'}
                        options={[
                            { value: 'before', label: __('Before amount', 'appointly') + ' (\u20AC100)' },
                            { value: 'after',  label: __('After amount', 'appointly') + ' (100\u20AC)' },
                        ]}
                        onChange={(val) => updateField('currency_position', val)}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <RadioControl
                        label={__('Theme Mode', 'appointly')}
                        selected={settings.theme_mode || 'auto'}
                        options={[
                            { value: 'auto', label: __('Auto (follows device setting)', 'appointly') },
                            { value: 'light', label: __('Always Light', 'appointly') },
                            { value: 'dark', label: __('Always Dark', 'appointly') },
                        ]}
                        onChange={(val) => updateField('theme_mode', val)}
                        help={__('Controls the calendar appearance and email templates.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <SelectControl
                        label={__('Email Language', 'appointly')}
                        value={settings.email_language || ''}
                        options={[
                            { value: '',       label: __('Match site language (default)', 'appointly') },
                            { value: 'de_DE',  label: 'Deutsch (Deutschland)' },
                            { value: 'de_AT',  label: 'Deutsch (\u00d6sterreich)' },
                            { value: 'de_CH',  label: 'Deutsch (Schweiz)' },
                            { value: 'en_US',  label: 'English (US)' },
                        ]}
                        onChange={(val) => updateField('email_language', val)}
                        help={__('Customer emails are always rendered in the site\u2019s language (Settings → General → Site Language), never the admin\u2019s personal profile language. Use this override only if you need emails in a different language than what customers see on the booking form.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />

                </div>
            </SettingsPanel>

            {/* Booking Defaults */}
            <SettingsPanel
                title={__('Booking Defaults', 'appointly')}
                icon="calendar-alt"
            >
                <div className="appointly-settings__fields">
                    <RadioControl
                        label={__('Availability scope', 'appointly')}
                        selected={settings.availability_scope || 'shared'}
                        options={[
                            {
                                value: 'shared',
                                label: __('Shared — one booking blocks all services (recommended for solo providers)', 'appointly'),
                            },
                            {
                                value: 'per_service',
                                label: __('Per service — each service has its own independent calendar (multi-staff / multi-room businesses)', 'appointly'),
                            },
                        ]}
                        onChange={(val) => updateField('availability_scope', val)}
                        help={__('Shared is the right default for a photographer, consultant, therapist, or coach who cannot be in two places at once. Per-service is correct for a yoga studio with parallel classes in different rooms, or a salon with multiple staff.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />

                    <TextControl
                        label={__('Default Min Lead Days', 'appointly')}
                        value={String(settings.default_min_lead_days ?? 1)}
                        onChange={(val) => updateField('default_min_lead_days', parseInt(val, 10) || 0)}
                        type="number"
                        min={0}
                        help={__('Minimum number of days in advance a booking can be made.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <TextControl
                        label={__('Rate Limit Seconds', 'appointly')}
                        value={String(settings.rate_limit_seconds ?? 60)}
                        onChange={(val) => updateField('rate_limit_seconds', parseInt(val, 10) || 0)}
                        type="number"
                        min={0}
                        help={__('Minimum seconds between submissions from same IP.', 'appointly')}
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                    <ToggleControl
                        label={__('Honeypot Enabled', 'appointly')}
                        checked={!!settings.honeypot_enabled}
                        onChange={(val) => updateField('honeypot_enabled', val)}
                        help={__('Add a hidden field to catch spam bots.', 'appointly')}
                        __nextHasNoMarginBottom={ true }
                    />
                    <ToggleControl
                        label={__('Show calendar hint', 'appointly')}
                        checked={settings.show_date_hint !== false}
                        onChange={(val) => updateField('show_date_hint', val)}
                        help={__('Show "Already requested dates can still be inquired about" below the calendar.', 'appointly')}
                        __nextHasNoMarginBottom={ true }
                    />
                </div>
            </SettingsPanel>

            {/* Email Delivery (SMTP) */}
            <SettingsPanel
                title={__('Email Delivery (SMTP)', 'appointly')}
                icon="email"
                defaultOpen={!settings.smtp_host}
            >
                <div className="appointly-settings__fields">
                    <p className="appointly-settings__help-text">
                        {__('Configure SMTP to ensure booking emails reach your customers reliably. Select your email provider below to auto-fill the server settings.', 'appointly')}
                    </p>
                    <div className="appointly-settings__smtp">
                        <SelectControl
                                label={__('Email Provider', 'appointly')}
                                value=""
                                options={[
                                    { value: '', label: __('Select provider to auto-fill...', 'appointly') },
                                    { value: 'gmail', label: 'Gmail (Google)' },
                                    { value: 'outlook', label: 'Outlook / Microsoft 365' },
                                    { value: 'yahoo', label: 'Yahoo Mail' },
                                    { value: 'icloud', label: 'iCloud (Apple)' },
                                    { value: 'ionos', label: 'IONOS (1&1)' },
                                    { value: 'strato', label: 'Strato' },
                                    { value: 'world4you', label: 'World4You' },
                                    { value: 'hosteurope', label: 'Host Europe' },
                                    { value: 'allinkl', label: 'ALL-INKL' },
                                    { value: 'hetzner', label: 'Hetzner' },
                                    { value: 'ovh', label: 'OVH' },
                                    { value: 'zoho', label: 'Zoho Mail' },
                                    { value: 'sendgrid', label: 'SendGrid' },
                                    { value: 'mailgun', label: 'Mailgun' },
                                    { value: 'brevo', label: 'Brevo (Sendinblue)' },
                                    { value: 'custom', label: __('Other / Custom', 'appointly') },
                                ]}
                                onChange={(provider) => {
                                    const presets = {
                                        gmail:      { smtp_host: 'smtp.gmail.com',           smtp_port: 587, smtp_encryption: 'tls' },
                                        outlook:    { smtp_host: 'smtp.office365.com',       smtp_port: 587, smtp_encryption: 'tls' },
                                        yahoo:      { smtp_host: 'smtp.mail.yahoo.com',      smtp_port: 587, smtp_encryption: 'tls' },
                                        icloud:     { smtp_host: 'smtp.mail.me.com',         smtp_port: 587, smtp_encryption: 'tls' },
                                        ionos:      { smtp_host: 'smtp.ionos.de',            smtp_port: 587, smtp_encryption: 'tls' },
                                        strato:     { smtp_host: 'smtp.strato.de',           smtp_port: 465, smtp_encryption: 'ssl' },
                                        world4you:  { smtp_host: 'smtp.world4you.com',       smtp_port: 587, smtp_encryption: 'tls' },
                                        hosteurope: { smtp_host: 'smtp.hosteurope.de',       smtp_port: 587, smtp_encryption: 'tls' },
                                        allinkl:    { smtp_host: 'smtp.all-inkl.com',        smtp_port: 587, smtp_encryption: 'tls' },
                                        hetzner:    { smtp_host: 'smtp.your-server.de',      smtp_port: 587, smtp_encryption: 'tls' },
                                        ovh:        { smtp_host: 'ssl0.ovh.net',             smtp_port: 587, smtp_encryption: 'tls' },
                                        zoho:       { smtp_host: 'smtp.zoho.eu',             smtp_port: 587, smtp_encryption: 'tls' },
                                        sendgrid:   { smtp_host: 'smtp.sendgrid.net',        smtp_port: 587, smtp_encryption: 'tls' },
                                        mailgun:    { smtp_host: 'smtp.mailgun.org',         smtp_port: 587, smtp_encryption: 'tls' },
                                        brevo:      { smtp_host: 'smtp-relay.brevo.com',     smtp_port: 587, smtp_encryption: 'tls' },
                                    };
                                    const preset = presets[provider];
                                    if (preset) {
                                        setSettings((prev) => ({ ...prev, ...preset }));
                                    }
                                }}
                                help={__('Select your email provider to auto-fill server settings. You still need to enter your username and password.', 'appointly')}
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <TextControl
                                label={__('SMTP Host', 'appointly')}
                                value={settings.smtp_host || ''}
                                onChange={(val) => updateField('smtp_host', val)}
                                placeholder="smtp.example.com"
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <TextControl
                                label={__('SMTP Port', 'appointly')}
                                value={String(settings.smtp_port || 587)}
                                onChange={(val) => updateField('smtp_port', parseInt(val, 10) || 587)}
                                type="number"
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <SelectControl
                                label={__('Encryption', 'appointly')}
                                value={settings.smtp_encryption || 'tls'}
                                options={[
                                    { value: 'tls',  label: 'TLS' },
                                    { value: 'ssl',  label: 'SSL' },
                                    { value: 'none', label: __('None', 'appointly') },
                                ]}
                                onChange={(val) => updateField('smtp_encryption', val)}
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <TextControl
                                label={__('Username (Email)', 'appointly')}
                                value={settings.smtp_user || ''}
                                onChange={(val) => updateField('smtp_user', val)}
                                placeholder="you@example.com"
                                help={__('Usually your full email address.', 'appointly')}
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                            <TextControl
                                label={__('Password', 'appointly')}
                                value={settings.smtp_pass || ''}
                                onChange={(val) => updateField('smtp_pass', val)}
                                type="password"
                                autoComplete="new-password"
                                help={__('For Gmail/iCloud: use an App Password, not your regular password.', 'appointly')}
                                __next40pxDefaultSize={ true }
                                __nextHasNoMarginBottom={ true }
                            />
                                <Button
                                    variant="secondary"
                                    onClick={handleTestSmtp}
                                    isBusy={testingSmtp}
                                    disabled={testingSmtp}
                                    className="appointly-settings__smtp-test"
                                >
                                    {testingSmtp
                                        ? __('Testing...', 'appointly')
                                        : __('Test Connection', 'appointly')}
                                </Button>
                        </div>
                    </div>
            </SettingsPanel>

            {/* Privacy / GDPR */}
            <SettingsPanel
                title={__('Privacy', 'appointly')}
                icon="shield"
            >
                <div className="appointly-settings__fields">
                    <TextControl
                        label={__('Privacy Policy URL', 'appointly')}
                        help={__('Link to your privacy policy page. Shown as a required consent checkbox on the booking form.', 'appointly')}
                        value={settings.privacy_policy_url || ''}
                        onChange={(val) => updateField('privacy_policy_url', val)}
                        type="url"
                        placeholder="https://appointly.tscholene.com/datenschutz"
                        __next40pxDefaultSize={ true }
                        __nextHasNoMarginBottom={ true }
                    />
                </div>
            </SettingsPanel>

            {/* Frontend Texts */}
            <SettingsPanel
                title={__('Frontend Texts', 'appointly')}
                icon="editor-textcolor"
            >
                <FrontendTextsEditor
                    texts={settings.text_overrides || {}}
                    onChange={(val) => updateField('text_overrides', val)}
                />
                <div className="appointly-settings__texts-actions">
                    <Button
                        variant="tertiary"
                        isDestructive
                        onClick={handleResetTexts}
                    >
                        {__('Reset All', 'appointly')}
                    </Button>
                </div>
            </SettingsPanel>

            <SettingsPanel
                title={__('Uninstall Behavior', 'appointly')}
                icon="trash"
            >
                <p>
                    {__('Control what happens when you delete the Appointly plugin from the WordPress Plugins screen. By default, all your data is preserved so you can safely deactivate or reinstall without losing bookings.', 'appointly')}
                </p>
                <ToggleControl
                    label={__('Remove all booking data on uninstall', 'appointly')}
                    help={__('When checked, deleting the plugin will permanently drop all bookings, services, blocked dates, email templates, and settings. Leave unchecked (recommended) to preserve your data when deactivating or reinstalling.', 'appointly')}
                    checked={!!settings.remove_data_on_uninstall}
                    onChange={(val) => updateField('remove_data_on_uninstall', val)}
                    __nextHasNoMarginBottom={ true }
                />
                {settings.remove_data_on_uninstall && (
                    <>
                        <div className="appointly-admin__alert appointly-admin__alert--warning">
                            {__('Warning: this will permanently delete all your booking data when the plugin is removed. There is no recovery.', 'appointly')}
                        </div>
                        <ToggleControl
                            label={__('Also remove auto-created pages', 'appointly')}
                            help={__('Deletes any pages that were auto-created by the setup wizard (marked with _appointly_auto_created meta). Your custom pages with the [appointly_calendar] shortcode are never touched.', 'appointly')}
                            checked={!!settings.remove_pages_on_uninstall}
                            onChange={(val) => updateField('remove_pages_on_uninstall', val)}
                            __nextHasNoMarginBottom={ true }
                        />
                    </>
                )}
            </SettingsPanel>

            {/* Pro extension panels — rendered only if Appointly Pro is active. */}
            {proSettingsPanels.map((panel) => {
                const PanelComponent = panel.component;
                if (!PanelComponent) return null;
                return (
                    <SettingsPanel
                        key={panel.key}
                        title={
                            <>
                                {panel.label}
                                <span className="appointly-editor-section__pro-badge">{__('Pro', 'appointly')}</span>
                            </>
                        }
                        icon="admin-plugins"
                    >
                        <div className="appointly-settings__fields">
                            {(() => {
                                try {
                                    return <PanelComponent settings={settings} onChange={updateField} />;
                                } catch (err) {
                                    console.error('Pro settings panel threw:', err);
                                    return null;
                                }
                            })()}
                        </div>
                    </SettingsPanel>
                );
            })}

            {/* Sticky save bar */}
            <div className="appointly-settings__save-bar">
                <Button
                    variant="primary"
                    onClick={handleSave}
                    isBusy={saving}
                    disabled={saving}
                >
                    {saving ? __('Saving...', 'appointly') : __('Save Settings', 'appointly')}
                </Button>
            </div>
        </div>
    );
}
