/**
 * 参加者リストページ
 *
 * イベント別の参加者一覧・ステータス変更・団体スタッフ展開。
 */
import { useState, useEffect, useCallback } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
	Button,
	TextControl,
	SelectControl,
	Notice,
	Modal,
} from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import DataTable from '../components/DataTable';
import useCan from '../hooks/useCan';
import GuideSection from '../components/GuideSection';

const STATUS_OPTIONS = [
	{ label: __( 'All Statuses', 'conferencemanager' ), value: '' },
	{ label: __( 'Pending', 'conferencemanager' ), value: 'pending' },
	{ label: __( 'Confirmed', 'conferencemanager' ), value: 'confirmed' },
	{ label: __( 'Paid', 'conferencemanager' ), value: 'paid' },
	{ label: __( 'Attended', 'conferencemanager' ), value: 'attended' },
	{ label: __( 'Cancel', 'conferencemanager' ), value: 'cancelled' },
];

const STATUS_LABELS = Object.fromEntries( STATUS_OPTIONS.filter( ( o ) => o.value ).map( ( o ) => [ o.value, o.label ] ) );

const COLUMNS = [
	{ key: 'registration_no', label: __( 'Reg. No.', 'conferencemanager' ) },
	{ key: 'event_title', label: __( 'Event', 'conferencemanager' ) },
	{ key: 'member_name', label: __( 'Name', 'conferencemanager' ),
		render: ( val, row ) => {
			if ( row.group_id && row.is_representative ) {
				return (
					<span>
						{ val }
						<span className="conf-manager-badge conf-manager-badge--group" title={ __( 'Group Representative', 'conferencemanager' ) }>
							{ __( 'Group', 'conferencemanager' ) }
							{ row.staff_count > 0 && ` (${ row.staff_count })` }
						</span>
					</span>
				);
			}
			return val;
		},
	},
	{ key: 'member_org', label: __( 'Organization', 'conferencemanager' ) },
	{ key: 'fee_type_label', label: __( 'Fee Category', 'conferencemanager' ),
		render: ( val ) => val || '—',
	},
	{ key: 'participation_type', label: __( 'Participation Type', 'conferencemanager' ),
		render: ( val ) => val === 'online' ? __( 'Online', 'conferencemanager' ) : __( 'Venue', 'conferencemanager' ),
	},
	{ key: 'amount', label: __( 'Amount', 'conferencemanager' ),
		render: ( val ) => val ? `¥${ Number( val ).toLocaleString() }` : '¥0',
	},
	{ key: 'transfer_note', label: __( 'Transfer Account Name Note', 'conferencemanager' ),
		render: ( val ) => val || '—',
	},
	{ key: 'status', label: __( 'Status', 'conferencemanager' ),
		render: ( val ) => STATUS_LABELS[ val ] || val,
	},
];

const EMPTY_STAFF = { name: '', email: '', participation_type: 'onsite', fee_type: '' };

export default function Participants() {
	const [ items, setItems ] = useState( [] );
	const [ total, setTotal ] = useState( 0 );
	const [ page, setPage ] = useState( 1 );
	const [ status, setStatus ] = useState( '' );
	const [ keyword, setKeyword ] = useState( '' );
	const [ eventId, setEventId ] = useState( '' );
	const [ events, setEvents ] = useState( [] );
	const [ loading, setLoading ] = useState( false );
	const [ notice, setNotice ] = useState( null );

	// 団体スタッフ展開
	const [ expandedGroupId, setExpandedGroupId ] = useState( null );
	const [ staffList, setStaffList ] = useState( [] );
	const [ staffLoading, setStaffLoading ] = useState( false );

	// スタッフ追加モーダル
	const [ addStaffModal, setAddStaffModal ] = useState( null ); // registration_id or null
	const [ newStaff, setNewStaff ] = useState( { ...EMPTY_STAFF } );

	// 参加区分の修正モーダル
	const [ feeEditReg, setFeeEditReg ] = useState( null ); // registration row or null
	const [ feeOptions, setFeeOptions ] = useState( null );
	const [ feeForm, setFeeForm ] = useState( { fee_type: '', participation_type: 'onsite' } );
	const [ feeLoading, setFeeLoading ] = useState( false );
	const [ feeSaving, setFeeSaving ] = useState( false );

	useEffect( () => {
		apiFetch( { path: '/conf-manager/v1/events?per_page=100&status=active' } )
			.then( ( data ) => setEvents( Array.isArray( data ) ? data : [] ) )
			.catch( () => {} );
	}, [] );

	const eventOptions = [
		{ label: __( 'All Events', 'conferencemanager' ), value: '' },
		...events.map( ( e ) => ( { label: e.title, value: String( e.id ) } ) ),
	];

	const fetchItems = useCallback( async () => {
		setLoading( true );
		try {
			const params = new URLSearchParams( { page, per_page: 20 } );
			if ( status ) params.set( 'status', status );
			if ( keyword ) params.set( 'keyword', keyword );
			if ( eventId ) params.set( 'event_id', eventId );

			const response = await apiFetch( {
				path: `/conf-manager/v1/registrations?${ params }`,
				parse: false,
			} );
			const data = await response.json();
			setItems( data );
			setTotal( parseInt( response.headers.get( 'X-WP-Total' ) || '0' ) );
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
		} finally {
			setLoading( false );
		}
	}, [ page, status, keyword, eventId ] );

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

	const handleStatusChange = async ( regId, newStatus ) => {
		try {
			await apiFetch( {
				path: `/conf-manager/v1/registrations/${ regId }/status`,
				method: 'PUT',
				data: { status: newStatus },
			} );
			setNotice( { status: 'success', message: __( 'Status updated.', 'conferencemanager' ) } );
			fetchItems();
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
		}
	};

	// スタッフ一覧の取得/展開
	const toggleStaff = async ( regId ) => {
		if ( expandedGroupId === regId ) {
			setExpandedGroupId( null );
			setStaffList( [] );
			return;
		}
		setExpandedGroupId( regId );
		setStaffLoading( true );
		try {
			const data = await apiFetch( { path: `/conf-manager/v1/registrations/${ regId }/staff` } );
			setStaffList( data );
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
			setStaffList( [] );
		} finally {
			setStaffLoading( false );
		}
	};

	// スタッフ追加
	const handleAddStaff = async () => {
		if ( ! addStaffModal ) return;
		try {
			await apiFetch( {
				path: `/conf-manager/v1/registrations/${ addStaffModal }/staff`,
				method: 'POST',
				data: newStaff,
			} );
			setNotice( { status: 'success', message: __( 'Staff added.', 'conferencemanager' ) } );
			setAddStaffModal( null );
			setNewStaff( { ...EMPTY_STAFF } );
			// リロード
			toggleStaff( expandedGroupId );
			fetchItems();
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
		}
	};

	// スタッフ削除
	const handleCancelStaff = async ( regId, staffId, staffName ) => {
		if ( ! window.confirm( `${ staffName } ${ __( 'Cancel this item?', 'conferencemanager' ) }` ) ) return;
		try {
			await apiFetch( {
				path: `/conf-manager/v1/registrations/${ regId }/staff/${ staffId }`,
				method: 'DELETE',
			} );
			setNotice( { status: 'success', message: __( 'Staff cancelled.', 'conferencemanager' ) } );
			// リロード
			toggleStaff( regId );
			fetchItems();
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
		}
	};

	// 参加区分の修正モーダルを開く
	const openFeeEdit = async ( row ) => {
		setFeeEditReg( row );
		setFeeOptions( null );
		setFeeLoading( true );
		try {
			const data = await apiFetch( { path: `/conf-manager/v1/registrations/${ row.id }/fee-options` } );
			setFeeOptions( data );
			setFeeForm( {
				fee_type: data.current.fee_type || '',
				participation_type: data.current.participation_type || 'onsite',
			} );
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
			setFeeEditReg( null );
		} finally {
			setFeeLoading( false );
		}
	};

	// 参加区分の修正を保存
	const handleSaveFeeClassification = async () => {
		if ( ! feeEditReg ) return;
		setFeeSaving( true );
		try {
			await apiFetch( {
				path: `/conf-manager/v1/registrations/${ feeEditReg.id }/fee-classification`,
				method: 'PUT',
				data: feeForm,
			} );
			setNotice( { status: 'success', message: __( 'Fee classification updated.', 'conferencemanager' ) } );
			setFeeEditReg( null );
			setFeeOptions( null );
			fetchItems();
		} catch ( err ) {
			setNotice( { status: 'error', message: err.message } );
		} finally {
			setFeeSaving( false );
		}
	};

	const canEdit = useCan( 'conf_manager_edit_registrations' );

	const columnsWithAction = canEdit ? [
		...COLUMNS,
		{
			key: 'actions',
			label: __( 'Actions', 'conferencemanager' ),
			render: ( _, row ) => {
				const buttons = [];

				// 団体展開ボタン
				if ( row.group_id && row.is_representative ) {
					buttons.push(
						<Button
							key="expand"
							variant="secondary"
							size="small"
							className="conf-manager-btn--staff-toggle"
							onClick={ ( e ) => { e.stopPropagation(); toggleStaff( row.id ); } }
						>
							{ expandedGroupId === row.id ? __( 'Close', 'conferencemanager' ) : __( 'Staff', 'conferencemanager' ) }
						</Button>
					);
				}

				// 参加区分の修正（個人申込・未入金のみ）
				if ( ! row.group_id && [ 'pending', 'confirmed' ].includes( row.status ) ) {
					buttons.push(
						<Button
							key="fee-edit"
							variant="secondary"
							size="small"
							onClick={ ( e ) => { e.stopPropagation(); openFeeEdit( row ); } }
						>
							{ __( 'Edit Category', 'conferencemanager' ) }
						</Button>
					);
				}

				// ステータス変更（attended は終端ステータスのため変更不可。
				// cancelled は誤操作リカバリ用に pending への復元を許可）
				if ( row.status !== 'attended' ) {
					const nextStatuses = {
						pending: [ 'confirmed', 'paid', 'cancelled' ],
						confirmed: [ 'paid', 'cancelled' ],
						paid: [ 'attended', 'cancelled' ],
						cancelled: [ 'pending' ],
					};
					const options = nextStatuses[ row.status ] || [];
					if ( options.length > 0 ) {
						buttons.push(
							<SelectControl
								key="status"
								value=""
								onChange={ ( val ) => val && handleStatusChange( row.id, val ) }
								options={ [
									{ label: __( 'Change...', 'conferencemanager' ), value: '' },
									...options.map( ( s ) => ( { label: STATUS_LABELS[ s ], value: s } ) ),
								] }
							/>
						);
					}
				}
				return <div style={ { display: 'flex', gap: '4px', alignItems: 'center' } }>{ buttons }</div>;
			},
		},
	] : COLUMNS;

	// テーブル行の後にスタッフ展開行を挿入するためのカスタムレンダリング
	const renderStaffRow = ( regId ) => {
		if ( expandedGroupId !== regId ) return null;

		return (
			<tr key={ `staff-${ regId }` } className="conf-manager-staff-row">
				<td colSpan={ columnsWithAction.length } style={ { padding: 0 } }>
					<div className="conf-manager-staff-panel">
						<div className="conf-manager-staff-panel__header">
							<strong>{ __( 'Group Staff List', 'conferencemanager' ) }</strong>
							{ canEdit && (
								<Button
									variant="primary"
									size="small"
									onClick={ () => { setNewStaff( { ...EMPTY_STAFF } ); setAddStaffModal( regId ); } }
								>
									{ __( '+ Add Staff', 'conferencemanager' ) }
								</Button>
							) }
						</div>
						{ staffLoading ? (
							<p style={ { padding: '8px 16px' } }>{ __( 'Loading...', 'conferencemanager' ) }</p>
						) : staffList.length === 0 ? (
							<p style={ { padding: '8px 16px', color: '#757575' } }>{ __( 'No staff members.', 'conferencemanager' ) }</p>
						) : (
							<table className="widefat striped conf-manager-staff-table">
								<thead>
									<tr>
										<th>{ __( 'Name', 'conferencemanager' ) }</th>
										<th>{ __( 'Email', 'conferencemanager' ) }</th>
										<th>{ __( 'Fee Category', 'conferencemanager' ) }</th>
										<th>{ __( 'Participation Type', 'conferencemanager' ) }</th>
										{ canEdit && <th>{ __( 'Actions', 'conferencemanager' ) }</th> }
									</tr>
								</thead>
								<tbody>
									{ staffList.map( ( s ) => (
										<tr key={ s.id }>
											<td>{ s.name }</td>
											<td>{ s.email }</td>
											<td>{ s.fee_type || '—' }</td>
											<td>{ s.participation_type === 'online' ? __( 'Online', 'conferencemanager' ) : __( 'Venue', 'conferencemanager' ) }</td>
											{ canEdit && (
												<td>
													<Button
														variant="secondary"
														isDestructive
														size="small"
														onClick={ () => handleCancelStaff( regId, s.id, s.name ) }
													>
														{ __( 'Delete', 'conferencemanager' ) }
													</Button>
												</td>
											) }
										</tr>
									) ) }
								</tbody>
							</table>
						) }
					</div>
				</td>
			</tr>
		);
	};

	return (
		<div>
			<div className="conf-manager-page-header">
				<h2>{ __( 'Participants', 'conferencemanager' ) }</h2>
			</div>

			<GuideSection
				hero={ {
					title: __( 'Centralized Registration Management', 'conferencemanager' ),
					description: __( 'Track event registrations in real-time with status management and group registration support.', 'conferencemanager' ),
				} }
				cards={ [
					{
						icon: <svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" strokeWidth="1.5"><polyline points="9 11 12 14 22 4" /><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11" /></svg>,
						title: __( 'Status Management', 'conferencemanager' ),
						description: __( 'Track participant progress through statuses: pending → confirmed → paid → attended.', 'conferencemanager' ),
						tips: [
							__( 'Automatically update status after payment confirmation', 'conferencemanager' ),
							__( 'Process cancellations easily from the list', 'conferencemanager' ),
							__( 'Filter by event and status', 'conferencemanager' ),
						],
					},
					{
						icon: <svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M23 21v-2a4 4 0 00-3-3.87" /><path d="M16 3.13a4 4 0 010 7.75" /></svg>,
						title: __( 'Group Registration', 'conferencemanager' ),
						description: __( 'Group registration allows a representative to register multiple participants at once.', 'conferencemanager' ),
						tips: [
							__( 'Representative registers all staff members together', 'conferencemanager' ),
							__( 'Individual certificates for each person', 'conferencemanager' ),
							__( 'Invoices are issued collectively to the representative', 'conferencemanager' ),
						],
					},
					{
						icon: <svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M21.21 15.89A10 10 0 118 2.83" /><path d="M22 12A10 10 0 0012 2v10z" /></svg>,
						title: __( 'Data Utilization', 'conferencemanager' ),
						description: __( 'Leverage registration data for efficient event management.', 'conferencemanager' ),
						tips: [
							__( 'Quickly find participants by registration number', 'conferencemanager' ),
							__( 'Monitor the ratio of onsite vs. online participation', 'conferencemanager' ),
							__( 'Notify participants by email when status changes', 'conferencemanager' ),
						],
					},
				] }
			/>

			{ notice && (
				<Notice status={ notice.status } onDismiss={ () => setNotice( null ) }>
					{ notice.message }
				</Notice>
			) }

			<form onSubmit={ ( e ) => { e.preventDefault(); setPage( 1 ); fetchItems(); } } className="conf-manager-search">
				<SelectControl value={ eventId } onChange={ ( val ) => { setEventId( val ); setPage( 1 ); } } options={ eventOptions } />
				<TextControl
					placeholder={ __( 'Search by registration no.', 'conferencemanager' ) }
					value={ keyword }
					onChange={ setKeyword }
				/>
				<SelectControl value={ status } onChange={ setStatus } options={ STATUS_OPTIONS } />
				<Button type="submit" className="conf-manager-btn--primary">
					{ __( 'Search', 'conferencemanager' ) }
				</Button>
			</form>

			{ /* DataTable + スタッフ展開行 */ }
			<div className="conf-manager-table">
				{ loading && (
					<div className="conf-manager-table__loading">
						{ __( 'Loading...', 'conferencemanager' ) }
					</div>
				) }
				<table className="widefat striped">
					<thead>
						<tr>
							{ columnsWithAction.map( ( col ) => (
								<th key={ col.key }>{ col.label }</th>
							) ) }
						</tr>
					</thead>
					<tbody>
						{ items.length === 0 && ! loading ? (
							<tr>
								<td colSpan={ columnsWithAction.length }>
									{ __( 'No data available.', 'conferencemanager' ) }
								</td>
							</tr>
						) : (
							items.flatMap( ( row, idx ) => {
								const mainRow = (
									<tr key={ row.id || idx }>
										{ columnsWithAction.map( ( col ) => (
											<td key={ col.key }>
												{ col.render
													? col.render( row[ col.key ], row )
													: row[ col.key ] ?? '' }
											</td>
										) ) }
									</tr>
								);
								const staffRow = ( row.group_id && row.is_representative )
									? renderStaffRow( row.id )
									: null;
								return staffRow ? [ mainRow, staffRow ] : [ mainRow ];
							} )
						) }
					</tbody>
				</table>

				{ total > 20 && (
					<div className="conf-manager-table__pagination">
						<Button
							variant="secondary"
							disabled={ page <= 1 }
							onClick={ () => setPage( page - 1 ) }
						>
							{ __( 'Previous', 'conferencemanager' ) }
						</Button>
						<span className="conf-manager-table__page-info">
							{ page } / { Math.max( 1, Math.ceil( total / 20 ) ) }
							{ ' ' }({ total }{ __( 'items', 'conferencemanager' ) })
						</span>
						<Button
							variant="secondary"
							disabled={ page >= Math.ceil( total / 20 ) }
							onClick={ () => setPage( page + 1 ) }
						>
							{ __( 'Next', 'conferencemanager' ) }
						</Button>
					</div>
				) }
			</div>

			{ /* スタッフ追加モーダル */ }
			{ addStaffModal && (
				<Modal
					title={ __( 'Add Staff', 'conferencemanager' ) }
					onRequestClose={ () => setAddStaffModal( null ) }
				>
					<TextControl
						label={ __( 'Name', 'conferencemanager' ) }
						value={ newStaff.name }
						onChange={ ( v ) => setNewStaff( ( prev ) => ( { ...prev, name: v } ) ) }
						required
					/>
					<TextControl
						label={ __( 'Email Address', 'conferencemanager' ) }
						type="email"
						value={ newStaff.email }
						onChange={ ( v ) => setNewStaff( ( prev ) => ( { ...prev, email: v } ) ) }
						required
					/>
					<SelectControl
						label={ __( 'Participation Type', 'conferencemanager' ) }
						value={ newStaff.participation_type }
						onChange={ ( v ) => setNewStaff( ( prev ) => ( { ...prev, participation_type: v } ) ) }
						options={ [
							{ label: __( 'Venue', 'conferencemanager' ), value: 'onsite' },
							{ label: __( 'Online', 'conferencemanager' ), value: 'online' },
						] }
					/>
					<TextControl
						label={ __( 'Fee Category (Optional)', 'conferencemanager' ) }
						value={ newStaff.fee_type }
						onChange={ ( v ) => setNewStaff( ( prev ) => ( { ...prev, fee_type: v } ) ) }
						help={ __( 'e.g., regular, student, general (blank applies representative\'s member type)', 'conferencemanager' ) }
					/>
					<div style={ { marginTop: '16px', display: 'flex', gap: '8px' } }>
						<Button variant="primary" onClick={ handleAddStaff }>
							{ __( 'Add', 'conferencemanager' ) }
						</Button>
						<Button variant="tertiary" onClick={ () => setAddStaffModal( null ) }>
							{ __( 'Cancel', 'conferencemanager' ) }
						</Button>
					</div>
				</Modal>
			) }

			{ /* 参加区分の修正モーダル */ }
			{ feeEditReg && (
				<Modal
					title={ __( 'Edit Participation Category', 'conferencemanager' ) }
					onRequestClose={ () => { setFeeEditReg( null ); setFeeOptions( null ); } }
				>
					{ feeLoading || ! feeOptions ? (
						<p>{ __( 'Loading...', 'conferencemanager' ) }</p>
					) : ! feeOptions.editable ? (
						<Notice status="warning" isDismissible={ false }>
							{ __( 'This registration cannot be edited (it may be paid, cancelled, or a group registration).', 'conferencemanager' ) }
						</Notice>
					) : (
						<>
							<p style={ { color: '#50575e' } }>
								{ feeEditReg.registration_no } / { feeEditReg.member_name }
							</p>
							<SelectControl
								label={ __( 'Fee Category', 'conferencemanager' ) }
								value={ feeForm.fee_type }
								onChange={ ( v ) => setFeeForm( ( prev ) => ( { ...prev, fee_type: v } ) ) }
								options={ feeOptions.fee_types.map( ( t ) => ( { label: t.label, value: t.key } ) ) }
							/>
							<SelectControl
								label={ __( 'Participation Type', 'conferencemanager' ) }
								value={ feeForm.participation_type }
								onChange={ ( v ) => setFeeForm( ( prev ) => ( { ...prev, participation_type: v } ) ) }
								options={ [
									{ label: __( 'Venue', 'conferencemanager' ), value: 'onsite' },
									{ label: __( 'Online', 'conferencemanager' ), value: 'online' },
								] }
							/>
							<p style={ { fontSize: '13px', margin: '8px 0' } }>
								{ sprintf(
									/* translators: %s: base fee amount */
									__( 'Base fee (excl. tax): ¥%s', 'conferencemanager' ),
									Number( feeOptions.fee_matrix?.[ feeForm.fee_type ]?.[ feeForm.participation_type ] ?? 0 ).toLocaleString()
								) }
							</p>
							<p style={ { fontSize: '12px', color: '#757575' } }>
								{ __( 'Session option fees are recalculated as well. If an invoice was already issued, it will be regenerated. The final amount appears in the list after saving.', 'conferencemanager' ) }
							</p>
							<div style={ { marginTop: '16px', display: 'flex', gap: '8px' } }>
								<Button variant="primary" isBusy={ feeSaving } disabled={ feeSaving } onClick={ handleSaveFeeClassification }>
									{ __( 'Save', 'conferencemanager' ) }
								</Button>
								<Button variant="tertiary" onClick={ () => { setFeeEditReg( null ); setFeeOptions( null ); } }>
									{ __( 'Cancel', 'conferencemanager' ) }
								</Button>
							</div>
						</>
					) }
				</Modal>
			) }
		</div>
	);
}
