import { useEffect, useState } from '@wordpress/element';
import SettingsLayout from '../layout/SettingsLayout';
import { SettingsCard, TextInput, ToggleInput, MultiSelectInput } from '../templates';
import { fetchOptions, saveOptions } from '../../api/settings';
import { showPromiseToast } from '../../utils';

const webhookEvents = [
    { key: 'login_success', label: 'Login Success' },
    { key: 'login_failed', label: 'Login Failed' },
    { key: 'password_reset_request', label: 'Password Reset Request' },
    { key: 'token_refresh', label: 'Token Refresh' },
    { key: 'brute_force_detected', label: 'Brute Force Detected' },
    { key: 'blocked_ip_attempt', label: 'Blocked IP Attempt' },
    { key: 'sso_exchange', label: 'SSO Exchange' },
];

const ssoAlgorithms = {
    HS256: 'HS256',
    RS256: 'RS256',
    ES256: 'ES256',
};

const normalizeWebhooks = (list) =>
    (Array.isArray(list) ? list : [])
        .map((item) => ({
            url: (item?.url || '').trim(),
            events: Array.isArray(item?.events) ? item.events.filter(Boolean) : [],
            secret: (item?.secret || '').trim(),
        }))
        .filter((item) => item.url);

const normalizeSsoConnections = (list) =>
    (Array.isArray(list) ? list : [])
        .map((item) => ({
            label: (item?.label || '').trim(),
            site_url: (item?.site_url || '').trim(),
            key: (item?.key || '').trim(),
            shared_secret: (item?.shared_secret || '').trim(),
            algorithm: item?.algorithm || 'HS256',
        }))
        .filter((item) => item.site_url && item.key && item.shared_secret);

const SecurityOptions = () => {
    const [options, setOptions] = useState({
        cors_enabled: true,
        cors_allowed_origins: ['*'],
        allow_token_refresh: true,
        allow_token_revoke: true,
        allow_multi_token_sessions: true,
        max_user_tokens: 5,
        brute_force_max_attempts: 5,
        brute_force_lockout: 15,
        ip_whitelist: [],
        ip_blacklist: [],
        device_limit_enabled: false,
        device_limit_max: 3,
        security_webhooks: [],
        webhook_secret: '',
        webhook_retry_attempts: 3,
        sso_enable: false,
        sso_connections: [],
    });

    useEffect(() => {
        const updateOptions = (settings) => setOptions((prev) => ({ ...prev, ...settings }));
        const res = fetchOptions({ updateOptions });
        showPromiseToast(res, 'Loading security settings');
    }, []);

    const updateOption = (value, key) => {
        setOptions({ ...options, [key]: value });
    };

    const onSave = () => {
        const payload = {
            ...options,
            ip_whitelist: parseList(options.ip_whitelist),
            ip_blacklist: parseList(options.ip_blacklist),
            cors_allowed_origins: parseList(options.cors_allowed_origins),
            security_webhooks: normalizeWebhooks(options.security_webhooks),
            sso_connections: normalizeSsoConnections(options.sso_connections),
        };
        const res = saveOptions({ options: payload });
        showPromiseToast(res, 'Saving', 'Security settings updated');
    };

    const parseList = (value) => {
        if (Array.isArray(value)) {
            return value;
        }
        return (value || '')
            .split(/[\n,]/)
            .map((item) => item.trim())
            .filter(Boolean);
    };

    const webhookList = Array.isArray(options.security_webhooks) ? options.security_webhooks : [];
    const ssoList = Array.isArray(options.sso_connections) ? options.sso_connections : [];

    const updateWebhookRow = (index, changes) => {
        const list = webhookList.slice();
        list[index] = { ...list[index], ...changes };
        updateOption(list, 'security_webhooks');
    };

    const addWebhook = () => {
        updateOption([...webhookList, { url: '', events: [], secret: '' }], 'security_webhooks');
    };

    const removeWebhook = (index) => {
        const list = webhookList.slice();
        list.splice(index, 1);
        updateOption(list, 'security_webhooks');
    };

    const updateSsoRow = (index, changes) => {
        const list = ssoList.slice();
        list[index] = { ...list[index], ...changes };
        updateOption(list, 'sso_connections');
    };

    const addSsoConnection = () => {
        updateOption([...ssoList, { label: '', site_url: '', key: '', shared_secret: '', algorithm: 'HS256' }], 'sso_connections');
    };

    const removeSsoConnection = (index) => {
        const list = ssoList.slice();
        list.splice(index, 1);
        updateOption(list, 'sso_connections');
    };

    return (
        <SettingsLayout>
            <SettingsCard
                title="CORS"
                description="Control REST API origins and headers."
                onSave={onSave}
            >
                <ToggleInput
                    id="cors_enabled"
                    label="Enable CORS"
                    description="Expose API endpoints to external clients."
                    value={!!options.cors_enabled}
                    setOption={updateOption}
                />
                <TextInput
                    id="cors_allowed_origins"
                    label="Allowed Origins"
                    description="Comma separated list. Use * to allow all."
                    value={Array.isArray(options.cors_allowed_origins) ? options.cors_allowed_origins.join(', ') : options.cors_allowed_origins}
                    setOption={updateOption}
                />
            </SettingsCard>

            <SettingsCard
                title="Token Lifecycle"
                description="Control refresh, revoke, and device policies."
                onSave={onSave}
            >
                <ToggleInput
                    id="allow_token_refresh"
                    label="Allow Refresh"
                    description="Enable refresh endpoint to obtain new tokens."
                    value={!!options.allow_token_refresh}
                    setOption={updateOption}
                />
                <ToggleInput
                    id="allow_token_revoke"
                    label="Allow Revoke"
                    description="Enable revocation endpoint for logout flows."
                    value={!!options.allow_token_revoke}
                    setOption={updateOption}
                />
                <ToggleInput
                    id="device_limit_enabled"
                    label="Device Limit"
                    description="Limit simultaneous devices per account."
                    value={!!options.device_limit_enabled}
                    setOption={updateOption}
                />
                {options.device_limit_enabled && (
                    <TextInput
                        id="device_limit_max"
                        label="Max Devices"
                        type="number"
                        value={options.device_limit_max}
                        setOption={updateOption}
                    />
                )}
                <ToggleInput
                    id="allow_multi_token_sessions"
                    label="Allow Multiple Tokens Per User"
                    description="Enable multi-device workflows without forcing logouts."
                    value={!!options.allow_multi_token_sessions}
                    setOption={updateOption}
                />
                <TextInput
                    id="max_user_tokens"
                    label="Max Active Tokens per User"
                    type="number"
                    value={options.max_user_tokens}
                    setOption={updateOption}
                    disabled={!options.allow_multi_token_sessions}
                />
            </SettingsCard>

            <SettingsCard
                title="Brute Force Protection"
                description="Lock suspicious logins automatically."
                onSave={onSave}
            >
                <TextInput
                    id="brute_force_max_attempts"
                    type="number"
                    label="Maximum Attempts"
                    value={options.brute_force_max_attempts}
                    setOption={updateOption}
                />
                <TextInput
                    id="brute_force_lockout"
                    type="number"
                    label="Lockout (minutes)"
                    value={options.brute_force_lockout}
                    setOption={updateOption}
                />
            </SettingsCard>

            <SettingsCard
                title="IP Access"
                description="Restrict API access to safe networks."
                onSave={onSave}
            >
                <div>
                    <label className="text-sm font-semibold text-gray-900">Whitelist</label>
                    <p className="text-sm text-gray-600">Only these IPs can reach the API (leave empty to allow all).</p>
                    <textarea
                        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                        rows="3"
                        value={Array.isArray(options.ip_whitelist) ? options.ip_whitelist.join('\n') : options.ip_whitelist}
                        onChange={(e) => updateOption(e.target.value, 'ip_whitelist')}
                    />
                </div>
                <div>
                    <label className="text-sm font-semibold text-gray-900">Blacklist</label>
                    <p className="text-sm text-gray-600">Block these IPs.</p>
                    <textarea
                        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                        rows="3"
                        value={Array.isArray(options.ip_blacklist) ? options.ip_blacklist.join('\n') : options.ip_blacklist}
                        onChange={(e) => updateOption(e.target.value, 'ip_blacklist')}
                    />
                </div>
            </SettingsCard>

            <SettingsCard
                title="Security Webhooks"
                description="Push real-time security events to your own infrastructure."
                onSave={onSave}
            >
                <div className="grid gap-4 md:grid-cols-3">
                    <TextInput
                        id="webhook_secret"
                        label="Default Signature Secret"
                        description="Used to sign webhook payloads (HMAC SHA256)."
                        value={options.webhook_secret || ''}
                        setOption={updateOption}
                    />
                    <TextInput
                        id="webhook_retry_attempts"
                        label="Retry Attempts"
                        type="number"
                        value={options.webhook_retry_attempts}
                        setOption={updateOption}
                    />
                </div>
                <div className="space-y-4 mt-6">
                    {webhookList.length === 0 && (
                        <p className="text-sm text-gray-500">No webhooks added yet.</p>
                    )}
                    {webhookList.map((webhook, index) => (
                        <div key={`webhook-${index}`} className="border border-gray-200 rounded-md p-4 space-y-3">
                            <div className="flex flex-col gap-2">
                                <label className="text-sm font-semibold text-gray-900">Webhook URL</label>
                                <input
                                    type="url"
                                    className="rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                    value={webhook.url || ''}
                                    onChange={(e) => updateWebhookRow(index, { url: e.target.value })}
                                    placeholder="https://example.com/webhooks/wp-auth"
                                />
                            </div>
                            <MultiSelectInput
                                id={`webhook-events-${index}`}
                                label="Events"
                                description="Choose which events should trigger this webhook."
                                values={webhook.events || []}
                                options={webhookEvents}
                                setOption={(value) => updateWebhookRow(index, { events: value })}
                            />
                            <div className="grid gap-4 md:grid-cols-2">
                                <div>
                                    <label className="text-sm font-semibold text-gray-900">Override Secret (optional)</label>
                                    <input
                                        type="text"
                                        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                        value={webhook.secret || ''}
                                        onChange={(e) => updateWebhookRow(index, { secret: e.target.value })}
                                    />
                                </div>
                                <div className="flex items-end justify-end">
                                    <button
                                        type="button"
                                        className="rounded-md bg-red-100 px-3 py-2 text-sm font-semibold text-red-700 hover:bg-red-200"
                                        onClick={() => removeWebhook(index)}
                                    >
                                        Remove
                                    </button>
                                </div>
                            </div>
                        </div>
                    ))}
                    <button
                        type="button"
                        className="rounded-md border border-dashed border-gray-300 px-3 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50"
                        onClick={addWebhook}
                    >
                        + Add Webhook
                    </button>
                </div>
            </SettingsCard>

            <SettingsCard
                title="Plugin-level SSO"
                description="Allow trusted WordPress sites to exchange JWTs seamlessly."
                onSave={onSave}
            >
                <ToggleInput
                    id="sso_enable"
                    label="Enable SSO"
                    description="Accept signed SSO requests from connected sites."
                    value={!!options.sso_enable}
                    setOption={updateOption}
                />
                {options.sso_enable && (
                    <div className="space-y-4 mt-6">
                        {ssoList.length === 0 && (
                            <p className="text-sm text-gray-500">No partner sites configured yet.</p>
                        )}
                        {ssoList.map((connection, index) => (
                            <div key={`sso-${index}`} className="border border-gray-200 rounded-md p-4 space-y-3">
                                <div className="grid gap-4 md:grid-cols-2">
                                    <div>
                                        <label className="text-sm font-semibold text-gray-900">Site Label</label>
                                        <input
                                            type="text"
                                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                            value={connection.label || ''}
                                            onChange={(e) => updateSsoRow(index, { label: e.target.value })}
                                        />
                                    </div>
                                    <div>
                                        <label className="text-sm font-semibold text-gray-900">Site URL</label>
                                        <input
                                            type="url"
                                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                            value={connection.site_url || ''}
                                            onChange={(e) => updateSsoRow(index, { site_url: e.target.value })}
                                            placeholder="https://network-site.com"
                                        />
                                    </div>
                                </div>
                                <div className="grid gap-4 md:grid-cols-2">
                                    <div>
                                        <label className="text-sm font-semibold text-gray-900">Connection Key</label>
                                        <input
                                            type="text"
                                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                            value={connection.key || ''}
                                            onChange={(e) => updateSsoRow(index, { key: e.target.value })}
                                            placeholder="site-a"
                                        />
                                    </div>
                                    <div>
                                        <label className="text-sm font-semibold text-gray-900">Shared Secret</label>
                                        <input
                                            type="text"
                                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                            value={connection.shared_secret || ''}
                                            onChange={(e) => updateSsoRow(index, { shared_secret: e.target.value })}
                                        />
                                    </div>
                                </div>
                                <div className="grid gap-4 md:grid-cols-2">
                                    <div>
                                        <label className="text-sm font-semibold text-gray-900">Algorithm</label>
                                        <select
                                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                                            value={connection.algorithm || 'HS256'}
                                            onChange={(e) => updateSsoRow(index, { algorithm: e.target.value })}
                                        >
                                            {Object.entries(ssoAlgorithms).map(([key, label]) => (
                                                <option key={key} value={key}>{label}</option>
                                            ))}
                                        </select>
                                    </div>
                                    <div className="flex items-end justify-end">
                                        <button
                                            type="button"
                                            className="rounded-md bg-red-100 px-3 py-2 text-sm font-semibold text-red-700 hover:bg-red-200"
                                            onClick={() => removeSsoConnection(index)}
                                        >
                                            Remove
                                        </button>
                                    </div>
                                </div>
                            </div>
                        ))}
                        <button
                            type="button"
                            className="rounded-md border border-dashed border-gray-300 px-3 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50"
                            onClick={addSsoConnection}
                        >
                            + Add Site
                        </button>
                    </div>
                )}
            </SettingsCard>
        </SettingsLayout>
    );
};

export default SecurityOptions;


