import { useCallback, useEffect, useMemo, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { GroupNav } from './components/GroupNav';
import { LoadingState } from './components/LoadingState';
import { ProfileSection } from './components/ProfileSection';
import { SectionPanel } from './components/SectionPanel';
import { SettingsToolbar } from './components/SettingsToolbar';
import { StatusBar } from './components/StatusBar';
import { WizardBanner } from './components/WizardBanner';
import { SaveBar } from './components/SaveBar';
import { loadSettingsPayload, markReactSettingsReady, runLegacyAjax, saveSettingsSection } from './api';

export default function App() {
	const [ payload, setPayload ] = useState( null );
	const [ values, setValues ] = useState( {} );
	const [ profiles, setProfiles ] = useState( null );
	const [ meta, setMeta ] = useState( null );
	const [ activeGroup, setActiveGroup ] = useState( 'setup' );
	const [ dirty, setDirty ] = useState( {} );
	const [ loading, setLoading ] = useState( true );
	const [ saving, setSaving ] = useState( false );
	const [ notice, setNotice ] = useState( null );
	const [ loadError, setLoadError ] = useState( '' );

	const applyServerPayload = useCallback( ( data ) => {
		if ( data.values ) {
			setValues( data.values );
		}
		if ( data.health ) {
			setPayload( ( prev ) => ( prev ? { ...prev, health: data.health } : prev ) );
		}
		if ( data.profiles ) {
			setProfiles( ( prev ) => ( { ...( prev || {} ), ...data.profiles } ) );
		}
		if ( data.meta ) {
			setMeta( data.meta );
		}
	}, [] );

	const load = useCallback( async () => {
		setLoading( true );
		setLoadError( '' );
		try {
			const data = await loadSettingsPayload();
			setPayload( data );
			setValues( data.values || {} );
			setProfiles( data.profiles || null );
			setMeta( data.meta || null );
			setDirty( {} );
			if ( data.groups && data.groups.length ) {
				setActiveGroup( data.groups[ 0 ].id );
			}
		} catch ( e ) {
			const msg = e && e.message ? String( e.message ) : __( 'Could not load settings.', 'newsroom-ai-assistant' );
			setLoadError( msg );
		} finally {
			markReactSettingsReady();
			setLoading( false );
		}
	}, [] );

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

	const activeGroupMeta = useMemo( () => {
		if ( ! payload || ! payload.groups ) {
			return null;
		}
		return payload.groups.find( ( g ) => g.id === activeGroup ) || payload.groups[ 0 ];
	}, [ payload, activeGroup ] );

	const onFieldChange = ( sectionId, key, val ) => {
		setValues( ( prev ) => ( {
			...prev,
			[ sectionId ]: {
				...( prev[ sectionId ] || {} ),
				[ key ]: val,
			},
		} ) );
		setDirty( ( prev ) => ( {
			...prev,
			[ sectionId ]: true,
		} ) );
		setNotice( null );
	};

	const saveSection = async ( sectionId ) => {
		if ( ! dirty[ sectionId ] ) {
			return;
		}
		const uiBefore = sectionId === 'ux' ? !! ( values.ux && values.ux.newsai_settings_ui ) : null;
		setSaving( true );
		setNotice( null );
		try {
			const res = await saveSettingsSection( sectionId, values[ sectionId ] || {} );
			if ( res.values ) {
				setValues( ( prev ) => {
					const next = { ...prev };
					Object.keys( res.values ).forEach( ( sid ) => {
						next[ sid ] = { ...( next[ sid ] || {} ), ...res.values[ sid ] };
					} );
					return next;
				} );
			}
			applyServerPayload( res );
			setDirty( ( prev ) => {
				const next = { ...prev };
				delete next[ sectionId ];
				return next;
			} );
			const savedLabel = payload?.i18n?.saved || __( 'Settings saved.', 'newsroom-ai-assistant' );
			if ( sectionId === 'ux' && uiBefore !== null ) {
				const uiAfter = !! ( res.values?.ux?.newsai_settings_ui ?? values.ux?.newsai_settings_ui );
				if ( uiBefore !== uiAfter ) {
					const reloadLabel = payload?.i18n?.reloadSettings || __( 'Reloading settings…', 'newsroom-ai-assistant' );
					setNotice( { type: 'success', text: reloadLabel } );
					const base = window.newsroomSettingsBoot?.settingsPageUrl || payload?.settingsPageUrl || '';
					window.location.href = uiAfter ? base : ( payload?.classicUrl || `${ base }&ui=classic` );
					return;
				}
			}
			setNotice( { type: 'success', text: savedLabel } );
		} catch ( e ) {
			const errLabel = payload?.i18n?.error || __( 'Could not save. Try again.', 'newsroom-ai-assistant' );
			const detail = e && e.message ? ` (${ e.message })` : '';
			setNotice( { type: 'error', text: errLabel + detail } );
		} finally {
			setSaving( false );
		}
	};

	const fieldLabels = payload?.i18n || {};
	const pro = payload?.pro || {};

	const handleGeneratePolicy = async ( policyKey, fieldKey, sectionId ) => {
		setNotice( null );
		try {
			const res = await runLegacyAjax( 'newsai_ai_generate_policy_page', { policy: policyKey } );
			const url = res?.url || '';
			if ( url && sectionId ) {
				setValues( ( prev ) => ( {
					...prev,
					[ sectionId ]: {
						...( prev[ sectionId ] || {} ),
						[ fieldKey ]: url,
					},
				} ) );
			}
			setNotice( { type: 'success', text: res?.message || fieldLabels.saved } );
		} catch ( e ) {
			setNotice( { type: 'error', text: e?.message || fieldLabels.error } );
		}
	};

	if ( loading ) {
		return <LoadingState label={ fieldLabels.loading || __( 'Loading settings…', 'newsroom-ai-assistant' ) } />;
	}

	if ( ! payload ) {
		const classicUrl = window.newsroomSettingsBoot?.classicUrl || 'admin.php?page=newsai-settings&tab=settings&ui=classic';
		return (
			<div className="newsroom-settings newsroom-settings--error">
				<p>{ __( 'React settings could not load. Classic settings are shown below.', 'newsroom-ai-assistant' ) }</p>
				{ loadError && <p className="newsroom-settings__error-detail"><code>{ loadError }</code></p> }
				<p><a className="button" href={ classicUrl }>{ __( 'Open classic settings only', 'newsroom-ai-assistant' ) }</a></p>
			</div>
		);
	}

	return (
		<div className="nros-page nros-page--settings newsroom-settings">
			<header className="nros-page__head nros-page__head--settings">
				<div>
					<h1 className="nros-page__title">{ fieldLabels.settingsTitle || 'Settings' }</h1>
					<p className="nros-page__sub newsroom-settings__guide">{ fieldLabels.guide }</p>
				</div>
				<StatusBar health={ payload.health } />
			</header>

			<SettingsToolbar
				classicUrl={ payload.classicUrl }
				switchClassicUrl={ payload.switchClassicUrl }
				dashboardUrl={ payload.dashboardPageUrl }
				i18n={ fieldLabels }
			/>

			<WizardBanner wizard={ payload.wizard } i18n={ fieldLabels } />

			{ notice && (
				<div className={ `newsroom-settings__notice newsroom-settings__notice--${ notice.type }` } role="status">
					{ notice.text }
				</div>
			) }

			<div className="newsroom-settings__layout">
				<GroupNav groups={ payload.groups } active={ activeGroup } onSelect={ setActiveGroup } />
				<div className="newsroom-settings__main">
					{ activeGroupMeta && (
						<div className="newsroom-settings__group-intro">
							<h3>{ activeGroupMeta.title }</h3>
							<p>{ activeGroupMeta.description }</p>
						</div>
					) }
					{ ( activeGroupMeta?.sections || [] ).map( ( sectionId ) => {
						const section = payload.sections[ sectionId ];
						if ( ! section ) {
							return null;
						}
						if ( section.type === 'profiles' ) {
							return (
								<ProfileSection
									key={ sectionId }
									section={ section }
									profiles={ profiles }
									i18n={ fieldLabels }
									setNotice={ setNotice }
									onApplied={ applyServerPayload }
								/>
							);
						}
						return (
							<SectionPanel
								key={ sectionId }
								section={ section }
								values={ values[ sectionId ] || {} }
								onChange={ ( key, val ) => onFieldChange( sectionId, key, val ) }
								isDirty={ !! dirty[ sectionId ] }
								onSave={ () => saveSection( sectionId ) }
								saving={ saving }
								saveLabel={ fieldLabels.save }
								savingLabel={ fieldLabels.saving }
								helpTitle={ fieldLabels.helpTitle }
								fieldLabels={ fieldLabels }
								i18n={ fieldLabels }
								meta={ meta }
								pro={ pro }
								setNotice={ setNotice }
								onActionDone={ applyServerPayload }
								onMetaUpdate={ setMeta }
								onGeneratePolicy={ ( policyKey, fieldKey ) => handleGeneratePolicy( policyKey, fieldKey, sectionId ) }
							/>
						);
					} ) }
				</div>
			</div>
			<SaveBar dirty={ dirty } onSaveAll={ () => Object.keys( dirty ).forEach( saveSection ) } saving={ saving } i18n={ fieldLabels } />
		</div>
	);
}
