/**
 * 参加申込フォーム
 *
 * イベント選択 → 会員認識 → セッション選択 → 料金確認 → 決済手段選択 → 申込送信
 */
import { useState, useEffect, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import SelfRegistrationForm from '../components/SelfRegistrationForm';
import GroupRegistrationForm from '../components/GroupRegistrationForm';
import { decorateMemberTypeLabels } from '../../common/member-type-label';

const STEPS = [ 'event', 'member', 'options', 'confirm' ];

const MEMBER_TYPE_LABELS_BASE = {
	regular: __( 'Regular Member', 'conferencemanager' ),
	student: __( 'Student Member', 'conferencemanager' ),
	associate: __( 'Associate Member', 'conferencemanager' ),
	honorary: __( 'Honorary Member', 'conferencemanager' ),
	general: __( 'Non-member', 'conferencemanager' ),
};

// 🔴 表示名の装飾はここ 1 箇所だけ。**元の定義（上）は 1 文字も変えない。**
// 学会の略称（初期設定）が入っていれば標準 5 区分にだけ前置する。
// ⚠️ サーバから来る値（`fee_type_label` など）は**サーバ側でだけ**装飾している。
//    ここで二重に通さないこと。
const MEMBER_TYPE_LABELS = decorateMemberTypeLabels( MEMBER_TYPE_LABELS_BASE );

const MEMBER_TYPES_ORDER = [ 'regular', 'student', 'associate', 'honorary', 'general' ];

export default function RegistrationForm() {
	const [ step, setStep ] = useState( 0 );
	const [ events, setEvents ] = useState( [] );
	const [ selectedEvent, setSelectedEvent ] = useState( null );
	const [ sessions, setSessions ] = useState( [] );
	const [ member, setMember ] = useState( null );
	const [ email, setEmail ] = useState( '' );
	const [ participationType, setParticipationType ] = useState( 'onsite' );
	const [ selectedSessions, setSelectedSessions ] = useState( [] );
	const [ paymentMethod, setPaymentMethod ] = useState( 'bank' );
	const [ transferNote, setTransferNote ] = useState( '' );
	const [ feeType, setFeeType ] = useState( '' );
	const [ fee, setFee ] = useState( null );
	const [ loading, setLoading ] = useState( false );
	const [ error, setError ] = useState( null );
	const [ result, setResult ] = useState( null );
	const [ showSelfRegister, setShowSelfRegister ] = useState( false );
	const [ notFound, setNotFound ] = useState( false );
	const [ registrationType, setRegistrationType ] = useState( '' ); // 'individual' or 'group'

	// イベント一覧取得
	useEffect( () => {
		apiFetch( { path: '/conf-manager/v1/public/events' } )
			.then( setEvents )
			.catch( ( err ) => setError( err.message ) );
	}, [] );

	// イベント選択時にセッション取得
	const selectEvent = async ( eventId ) => {
		try {
			const data = await apiFetch( { path: `/conf-manager/v1/public/events/${ eventId }` } );
			setSelectedEvent( data );
			setSessions( data.sessions || [] );
			setStep( 1 );
		} catch ( err ) {
			setError( err.message );
		}
	};

	// 会員検索
	const lookupMember = async () => {
		if ( ! email ) return;
		setLoading( true );
		setError( null );
		setNotFound( false );
		setShowSelfRegister( false );
		try {
			const data = await apiFetch( {
				path: '/conf-manager/v1/public/members/lookup',
				method: 'POST',
				data: { email },
			} );
			if ( data.found ) {
				setMember( data );
				setFeeType( resolveFeeType( data.member_type ) );
				setStep( 2 );
			} else {
				setNotFound( true );
			}
		} catch ( err ) {
			setError( err.message );
		} finally {
			setLoading( false );
		}
	};

	// 自己登録完了時のコールバック
	const handleSelfRegisterComplete = ( data ) => {
		setMember( {
			id: data.member_id,
			email_hash: data.email_hash,
			name_sei: data.name_sei,
			name_mei: data.name_mei,
			member_type: data.member_type,
			is_member: data.is_member,
			org_name: data.org_name || '',
			found: true,
		} );
		setShowSelfRegister( false );
		setError( null );
		setFeeType( resolveFeeType( data.member_type ) );
		setStep( 2 );
	};

	// fee_rules に member_type が存在しなければ最初の有効キーにフォールバック
	/**
	 * 料金が設定されている参加形態だけを返す
	 *
	 * 📌 これは画面側の出し分けでしかない。サーバー側（RegistrationManager::create()）が
	 *    同じ判定で断るので、REST を直接叩かれても通らない。
	 *
	 * 料金表が丸ごと空のイベント（＝無料イベント）や、その区分の行自体が無い場合は
	 * 従来どおり両方出す。サーバー側の判定と条件を揃えること。
	 */
	const availableParticipationTypes = () => {
		const all = [ 'onsite', 'online' ];
		const rules = selectedEvent?.current_fee_rules || selectedEvent?.fee_rules || {};
		const { _labels: ignored, ...typeRules } = rules;
		if ( Object.keys( typeRules ).length === 0 ) return all;

		const key = feeType || member?.member_type;
		const row = typeRules[ key ];
		if ( ! row || typeof row !== 'object' ) return all;

		const offered = all.filter( ( pt ) => Object.prototype.hasOwnProperty.call( row, pt ) );
		return offered.length > 0 ? offered : all;
	};

	// 選べなくなった参加形態が state に残ると、画面の表示と送る値がずれる
	useEffect( () => {
		const offered = availableParticipationTypes();
		if ( ! offered.includes( participationType ) ) {
			setParticipationType( offered[ 0 ] );
		}
	}, [ selectedEvent, feeType, member, participationType ] );

	const resolveFeeType = ( memberType ) => {
		const rules = selectedEvent?.current_fee_rules || selectedEvent?.fee_rules || {};
		if ( rules[ memberType ] ) return memberType;
		for ( const key of MEMBER_TYPES_ORDER ) {
			if ( rules[ key ] ) return key;
		}
		const labels = rules._labels || {};
		const customKeys = Object.keys( labels );
		if ( customKeys.length > 0 && rules[ customKeys[ 0 ] ] ) return customKeys[ 0 ];
		return memberType;
	};

	// イベントの fee_rules から料金種別の選択肢を生成
	const getFeeTypeOptions = () => {
		if ( ! selectedEvent ) return [];
		const rules = selectedEvent.current_fee_rules || selectedEvent.fee_rules || {};
		const labels = rules._labels || {};
		const options = [];
		// 固定種別
		MEMBER_TYPES_ORDER.forEach( ( key ) => {
			if ( rules[ key ] ) {
				options.push( { value: key, label: MEMBER_TYPE_LABELS[ key ] || key } );
			}
		} );
		// カスタム種別
		Object.keys( labels ).forEach( ( key ) => {
			if ( rules[ key ] ) {
				options.push( { value: key, label: labels[ key ] || key } );
			}
		} );
		return options;
	};

	// 前売/当日料金ラベル
	const getFeePeriodLabel = () => {
		if ( ! selectedEvent || selectedEvent.is_advance_period === null || selectedEvent.is_advance_period === undefined ) {
			return '';
		}
		return selectedEvent.is_advance_period
			? __( 'Advance Fee', 'conferencemanager' )
			: __( 'On-site Fee', 'conferencemanager' );
	};

	// 料金計算
	const calculateFee = useCallback( async () => {
		if ( ! selectedEvent || ! member ) return;
		const memberType = feeType || member.member_type;
		try {
			const params = new URLSearchParams( {
				member_type: memberType,
				participation_type: participationType,
			} );
			selectedSessions.forEach( ( sid ) => params.append( 'sessions[]', sid ) );

			const data = await apiFetch( {
				path: `/conf-manager/v1/public/events/${ selectedEvent.id }/fee?${ params }`,
			} );
			setFee( data );
		} catch ( err ) {
			setError( err.message );
		}
	}, [ selectedEvent, member, feeType, participationType, selectedSessions ] );

	// オプション確定時に料金計算してconfirmへ
	const proceedToConfirm = async () => {
		await calculateFee();
		setStep( 3 );
	};

	// 申込送信
	const submitRegistration = async () => {
		setLoading( true );
		setError( null );
		try {
			const data = await apiFetch( {
				path: '/conf-manager/v1/public/registrations',
				method: 'POST',
				data: {
					event_id: selectedEvent.id,
					member_id: member.id,
					email_hash: member.email_hash,
					participation_type: participationType,
					payment_method: paymentMethod,
					transfer_note: paymentMethod === 'bank' ? transferNote : '',
					session_options: selectedSessions,
					fee_type: feeType,
				},
			} );

			if ( data.error ) {
				setError( data.error );
				return;
			}

			setResult( data );
		} catch ( err ) {
			setError( err.message );
		} finally {
			setLoading( false );
		}
	};

	const toggleSession = ( id ) => {
		setSelectedSessions( ( prev ) =>
			prev.includes( id ) ? prev.filter( ( s ) => s !== id ) : [ ...prev, id ]
		);
	};

	// 完了画面
	if ( result ) {
		return (
			<div className="conf-manager-public conf-manager-form">
				<h2>{ __( 'Registration Complete', 'conferencemanager' ) }</h2>
				<div className="conf-manager-form__success">
					<p>{ result.group_id
						? __( 'Group registration received.', 'conferencemanager' )
						: __( 'Registration received.', 'conferencemanager' )
					}</p>
					<dl>
						<dt>{ __( 'Reg. No.', 'conferencemanager' ) }</dt>
						<dd>{ result.registration_no }</dd>
						{ result.staff_count > 0 && (
							<>
								<dt>{ __( 'Staff Count', 'conferencemanager' ) }</dt>
								<dd>{ result.staff_count }{ __( 'First Name', 'conferencemanager' ) }</dd>
							</>
						) }
						<dt>{ result.tax > 0 ? __( 'Amount (excl. tax)', 'conferencemanager' ) : __( 'Amount', 'conferencemanager' ) }</dt>
						<dd>&yen;{ result.amount.toLocaleString() }</dd>
						{ result.tax > 0 && (
							<>
								<dt>{ __( 'Tax', 'conferencemanager' ) }</dt>
								<dd>&yen;{ result.tax.toLocaleString() }</dd>
							</>
						) }
						{ result.tax > 0 && (
							<>
								<dt>{ __( 'Total', 'conferencemanager' ) }</dt>
								<dd>&yen;{ ( result.amount + result.tax ).toLocaleString() }</dd>
							</>
						) }
					</dl>
					{ paymentMethod === 'bank' && (
						<p>{ __( 'Bank transfer details will be sent by email.', 'conferencemanager' ) }</p>
					) }
				</div>
			</div>
		);
	}

	return (
		<div className="conf-manager-public conf-manager-form">
			<h2>{ __( 'Registration', 'conferencemanager' ) }</h2>

			{ /* ステップインジケーター */ }
			<div className="conf-manager-form__steps">
				{ [ __( 'Select Event', 'conferencemanager' ), __( 'Member Authentication', 'conferencemanager' ), __( 'Options', 'conferencemanager' ), __( 'Confirm & Submit', 'conferencemanager' ) ].map( ( label, i ) => (
					<span key={ i } className={ `conf-manager-form__step ${ i === step ? 'is-active' : '' } ${ i < step ? 'is-done' : '' }` }>
						{ i + 1 }. { label }
					</span>
				) ) }
			</div>

			{ error && <div className="conf-manager-form__error">{ error }</div> }

			{ /* Step 1: イベント選択 */ }
			{ step === 0 && (
				<div>
					<h3>{ __( 'Please select an event', 'conferencemanager' ) }</h3>
					{ events.length === 0 ? (
						<p>{ __( 'No events available for registration.', 'conferencemanager' ) }</p>
					) : (
						<ul className="conf-manager-form__event-list">
							{ events.map( ( ev ) => (
								<li key={ ev.id }>
									<button onClick={ () => selectEvent( ev.id ) } className="conf-manager-form__event-card">
										<strong>{ new Date( ev.date_start ) >= new Date( new Date().toDateString() ) && <span className="conf-manager-form__event-badge"></span> }{ ev.title }</strong>
										<span>{ ev.date_start.substring( 0, 10 ) } / { ev.venue }</span>
									</button>
								</li>
							) ) }
						</ul>
					) }
				</div>
			) }

			{ /* Step 2: 会員認証 */ }
			{ step === 1 && ! showSelfRegister && (
				<div>
					<h3>{ __( 'Enter Email Address', 'conferencemanager' ) }</h3>
					<p>{ __( 'Enter your email address. Registered users can proceed directly. New users can register.', 'conferencemanager' ) }</p>
					<div className="conf-manager-form__field">
						<input type="email" value={ email } onChange={ ( e ) => { setEmail( e.target.value ); setNotFound( false ); } } placeholder="example@email.com" />
						<button onClick={ lookupMember } disabled={ loading } className="conf-manager-form__next">
							{ loading ? __( 'Verifying...', 'conferencemanager' ) : __( 'Next', 'conferencemanager' ) }
						</button>
					</div>
					{ notFound && (
						<div className="conf-manager-form__not-found">
							<p>{ __( 'This email address is not registered.', 'conferencemanager' ) }</p>
							<div className="conf-manager-form__actions">
								<button onClick={ () => { setStep( 0 ); setNotFound( false ); } } className="conf-manager-form__back">
									{ __( 'Back', 'conferencemanager' ) }
								</button>
								<button
									onClick={ () => setShowSelfRegister( true ) }
									className="conf-manager-form__register-new"
								>
									{ __( 'Register as New', 'conferencemanager' ) }
								</button>
							</div>
						</div>
					) }
					{ member && ! notFound && (
						<div className="conf-manager-form__member-info">
							<p>
								{ __( 'Membership registration for this email address has been confirmed.', 'conferencemanager' ) }
								{ ` （${ MEMBER_TYPE_LABELS[ member.member_type ] || selectedEvent?.fee_rules?._labels?.[ member.member_type ] || member.member_type }）` }
							</p>
						</div>
					) }
					{ ! notFound && (
						<button onClick={ () => { setStep( 0 ); setNotFound( false ); } } className="conf-manager-form__back">{ __( 'Back', 'conferencemanager' ) }</button>
					) }
				</div>
			) }

			{ /* Step 2b: 自己登録フォーム */ }
			{ step === 1 && showSelfRegister && (
				<SelfRegistrationForm
					email={ email }
					onComplete={ handleSelfRegisterComplete }
					onCancel={ () => { setShowSelfRegister( false ); setNotFound( false ); } }
				/>
			) }

			{ /* Step 2c: 個人/団体選択 */ }
			{ step === 2 && registrationType === '' && (
				<div>
					<h3>{ __( 'Select Registration Type', 'conferencemanager' ) }</h3>
					<div className="conf-manager-form__type-select">
						<button
							onClick={ () => setRegistrationType( 'individual' ) }
							className="conf-manager-form__event-card"
						>
							<strong>{ __( 'Individual Registration', 'conferencemanager' ) }</strong>
							<span>{ __( 'Register only yourself', 'conferencemanager' ) }</span>
						</button>
						<button
							onClick={ () => setRegistrationType( 'group' ) }
							className="conf-manager-form__event-card"
						>
							<strong>{ __( 'Group Registration', 'conferencemanager' ) }</strong>
							<span>{ __( 'Register representative + staff together', 'conferencemanager' ) }</span>
						</button>
					</div>
					<button onClick={ () => setStep( 1 ) } className="conf-manager-form__back">{ __( 'Back', 'conferencemanager' ) }</button>
				</div>
			) }

			{ /* Step 2d: 団体申込フォーム */ }
			{ step === 2 && registrationType === 'group' && (
				<GroupRegistrationForm
					selectedEvent={ selectedEvent }
					member={ member }
					sessions={ sessions }
					onSubmit={ ( data ) => setResult( data ) }
					onBack={ () => setRegistrationType( '' ) }
				/>
			) }

			{ /* Step 3: オプション選択（個人） */ }
			{ step === 2 && registrationType === 'individual' && (
				<div>
					<h3>{ __( 'Participation Options', 'conferencemanager' ) }</h3>

					{ selectedEvent?.advance_fee_deadline && (
						<div className={ `conf-manager-form__fee-notice ${ selectedEvent.is_advance_period ? 'is-advance' : 'is-day' }` }>
							{ selectedEvent.is_advance_period
								? __( 'Advance pricing applied', 'conferencemanager' ) + `（${ selectedEvent.advance_fee_deadline.substring( 0, 10 ) } ${ __( 'until', 'conferencemanager' ) }）`
								: __( 'On-site pricing applies.', 'conferencemanager' )
							}
							{ selectedEvent.advance_fee_notice && (
								<p style={ { margin: '4px 0 0', fontSize: '13px' } }>{ selectedEvent.advance_fee_notice }</p>
							) }
						</div>
					) }

					{ getFeeTypeOptions().length > 1 && (
						<div className="conf-manager-form__field">
							<label>{ __( 'Participation Type (Fee Category)', 'conferencemanager' ) }</label>
							<select value={ feeType } onChange={ ( e ) => setFeeType( e.target.value ) }>
								{ getFeeTypeOptions().map( ( opt ) => (
									<option key={ opt.value } value={ opt.value }>{ opt.label }</option>
								) ) }
							</select>
						</div>
					) }

					<div className="conf-manager-form__field">
						<label>{ __( 'Select Participation Type', 'conferencemanager' ) }</label>
						<select value={ participationType } onChange={ ( e ) => setParticipationType( e.target.value ) }>
							{ availableParticipationTypes().map( ( pt ) => (
								<option key={ pt } value={ pt }>
									{ pt === 'online'
										? __( 'Online Participation', 'conferencemanager' )
										: __( 'On-site', 'conferencemanager' ) }
								</option>
							) ) }
						</select>
					</div>

					{ sessions.filter( ( s ) => s.fee > 0 ).length > 0 && (
						<div className="conf-manager-form__field">
							<label>{ __( 'Additional Sessions (paid)', 'conferencemanager' ) }</label>
							{ sessions.filter( ( s ) => s.fee > 0 ).map( ( s ) => (
								<label key={ s.id } className="conf-manager-form__checkbox">
									<input type="checkbox" checked={ selectedSessions.includes( s.id ) } onChange={ () => toggleSession( s.id ) } />
									{ s.title } (&yen;{ s.fee.toLocaleString() })
								</label>
							) ) }
						</div>
					) }

					<div className="conf-manager-form__field">
						<label>{ __( 'Payment Method', 'conferencemanager' ) }</label>
						<select value={ paymentMethod } onChange={ ( e ) => setPaymentMethod( e.target.value ) }>
							{ ( window.confManagerPayment?.methods || [ 'bank' ] ).includes( 'bank' ) && (
								<option value="bank">{ __( 'Bank Transfer', 'conferencemanager' ) }</option>
							) }
						</select>
					</div>

					{ paymentMethod === 'bank' && (
						<div className="conf-manager-form__field">
							<label>{ __( 'Transfer Account Name Note', 'conferencemanager' ) }</label>
							<input
								type="text"
								maxLength={ 255 }
								value={ transferNote }
								onChange={ ( e ) => setTransferNote( e.target.value ) }
							/>
							<p className="conf-manager-form__hint">{ __( 'If the bank transfer will be made under a name different from the participant, please note it here. Leave blank if it is the same as the participant name.', 'conferencemanager' ) }</p>
						</div>
					) }

					<div className="conf-manager-form__actions">
						<button onClick={ () => setRegistrationType( '' ) } className="conf-manager-form__back">{ __( 'Back', 'conferencemanager' ) }</button>
						<button onClick={ proceedToConfirm } className="conf-manager-form__next">{ __( 'Proceed to Confirm', 'conferencemanager' ) }</button>
					</div>
				</div>
			) }

			{ /* Step 4: 確認・送信 */ }
			{ step === 3 && (
				<div>
					<h3>{ __( 'Confirm Registration', 'conferencemanager' ) }</h3>
					<dl className="conf-manager-form__confirm-list">
						<dt>{ __( 'Event', 'conferencemanager' ) }</dt>
						<dd>{ selectedEvent.title }</dd>
						{ member.name_sei && (
							<>
								<dt>{ __( 'Name', 'conferencemanager' ) }</dt>
								<dd>{ member.name_sei } { member.name_mei }</dd>
							</>
						) }
						<dt>{ __( 'Participation Type', 'conferencemanager' ) }</dt>
						<dd>{ MEMBER_TYPE_LABELS[ feeType ] || selectedEvent?.fee_rules?._labels?.[ feeType ] || feeType }</dd>
						<dt>{ __( 'Participation Type', 'conferencemanager' ) }</dt>
						<dd>{ participationType === 'online' ? __( 'Online', 'conferencemanager' ) : __( 'On-site', 'conferencemanager' ) }</dd>
						<dt>{ __( 'Payment Method', 'conferencemanager' ) }</dt>
						<dd>{ __( 'Bank Transfer', 'conferencemanager' ) }</dd>
						{ paymentMethod === 'bank' && transferNote && (
							<>
								<dt>{ __( 'Transfer Account Name Note', 'conferencemanager' ) }</dt>
								<dd>{ transferNote }</dd>
							</>
						) }
						{ fee && (
							<>
								<dt>{ fee.tax > 0
									? ( getFeePeriodLabel() ? `${ __( 'Participation Fee', 'conferencemanager' ) }（${ getFeePeriodLabel() }・${ __( 'excl. tax', 'conferencemanager' ) }）` : __( 'Fee (excl. tax)', 'conferencemanager' ) )
									: ( getFeePeriodLabel() ? `${ __( 'Participation Fee', 'conferencemanager' ) }（${ getFeePeriodLabel() }）` : __( 'Participation Fee', 'conferencemanager' ) )
								}</dt>
								<dd>&yen;{ fee.amount.toLocaleString() }</dd>
								{ fee.tax > 0 && (
									<>
										<dt>{ __( 'Tax', 'conferencemanager' ) }</dt>
										<dd>&yen;{ fee.tax.toLocaleString() }</dd>
										<dt>{ __( 'Total', 'conferencemanager' ) }</dt>
										<dd><strong>&yen;{ fee.total.toLocaleString() }</strong></dd>
									</>
								) }
							</>
						) }
					</dl>

					<div className="conf-manager-form__actions">
						<button onClick={ () => setStep( 2 ) } className="conf-manager-form__back">{ __( 'Back', 'conferencemanager' ) }</button>
						<button onClick={ submitRegistration } disabled={ loading } className="conf-manager-form__submit">
							{ loading ? __( 'Submitting...', 'conferencemanager' ) : __( 'Submit Registration', 'conferencemanager' ) }
						</button>
					</div>
				</div>
			) }

		</div>
	);
}
