import {__} from '@wordpress/i18n';
import {useMemo} from '@wordpress/element';
import {dateI18n} from '@wordpress/date';
import '../../../../admin/assets/design/scss/_sortable_table_header.scss';

const formatNumber = ( num ) => new Intl.NumberFormat( 'default' ).format( Math.round( num ) );
const formatPercent = ( num ) => `${num.toFixed( 2 )}%`;
const {dateFormat} = window.adpressoAnalyticsData || {dateFormat: 'F j, Y'};

/**
 * A small subcomponent that renders the comparing.
 */
const CompareCell = ( {metricA, metricB, format} ) => {
	// Berechne Delta (absolut) und Delta (prozentual)
	const delta = metricA - metricB;
	const deltaPercent = (metricB === 0)
		? (metricA > 0 ? 100 : 0) // Division durch Null abfangen
		: ((metricA - metricB) / metricB) * 100;

	return (
		<div className="adpresso-compare-cell">
			<span className="adpresso-compare-cell__current">{format( metricA )}</span>
			<span className="adpresso-compare-cell__previous">
                {format( metricB )}
				<span className={`adpresso-compare-cell__delta ${delta > 0 ? 'is-positive' : 'is-negative'}`}>
                    ({delta > 0 ? '+' : ''}{formatNumber( delta )}, {deltaPercent.toFixed( 1 )}%)
                </span>
            </span>
		</div>
	);
};

const DataTable = ( {tableData, isPro, viewMode, sorting, onSort, compareData = null, onDrilldown, visibleColumns = {}} ) => {

	const showCol = ( key ) => visibleColumns[key] !== false;

	// Um die ColSpan Berechnung dynamisch zu machen bei "No data"
	const getVisibleColumnCount = () => {
		let count = 1; // Erste Spalte ist immer da
		if ( showCol( 'impressions' ) ) {
			count ++;
		}
		if ( isPro && showCol( 'impressions_av' ) ) {
			count ++;
		}
		if ( showCol( 'clicks' ) ) {
			count ++;
		}
		if ( showCol( 'ctr' ) ) {
			count ++;
		}
		if ( isPro && showCol( 'viewability' ) ) {
			count ++;
		}
		return count;
	};

	const SortableHeader = ( {label, columnKey} ) => {
		const isSorted = sorting.orderBy === columnKey;
		const newOrder = (isSorted && sorting.order === 'asc') ? 'desc' : 'asc';
		const ariaSort = isSorted ? (sorting.order === 'asc' ? 'ascending' : 'descending') : 'none';

		return (
			<th
				scope="col"
				className={`sortable ${isSorted ? 'sorted ' + sorting.order : ''}`}
				// aria-sort={ariaSort}
				// onClick={() => onSort( {orderBy: columnKey, order: newOrder} )}
				onClick={( e ) => {
					e.preventDefault();
					onSort( {orderBy: columnKey, order: newOrder} );
				}}
			>
				<a href="#">
					<span>{label}</span>
				</a>
				<button
					type="button"
					className={`adpresso-th__sort ${isSorted ? `is-sorted ${sorting.order}` : ''}`}
					aria-label={isSorted ? (sorting.order === 'asc' ? 'Sort ascending' : 'Sort descending') : 'Sort'}
				>
						<span className="adpresso-th__chevrons">
							<span className="chev up"></span>
							<span className="chev down"></span>
						</span>
				</button>
			</th>
		);
	};

	const getFirstColumnHeader = () => {
		switch ( viewMode ) {
			case 'ads':
				return __( 'Ad', 'adpresso' );
			case 'groups':
				return __( 'Group', 'adpresso' );
			case 'placements':
				return __( 'Placement', 'adpresso' );
			case 'date':
			default:
				return __( 'Date', 'adpresso' );
		}
	};
	const renderFirstColumn = ( row ) => {
		let content;
		let drilldownParams = null;
		let rowId = 0;
		switch ( viewMode ) {
			case 'ads':
				content = row.name || '(No Title)';
				break;
			case 'groups':
				rowId = row.group_id;
				content = row.name || '(No Title)';
				drilldownParams = {
					viewMode: 'ads',
					filters:  {groups: [rowId]}
				};
				break;
			case 'placements':
				rowId = row.placement_id;
				content = row.name || '(No Title)';
				// Define the action for the drilldown. Show ads filtered by this placement.
				// Zeige Anzeigen, gefiltert nach diesem Placement
				drilldownParams = {
					viewMode: 'ads',
					filters:  {placements: [rowId]}
				};
				break;
			case 'date':
			default:
				if ( row.date ) {
					try {
						return dateI18n( dateFormat, `${row.date}T12:00:00` );
					} catch ( e ) {
						return row.date;
					}
				}
				return '-';
		}

		if ( false && drilldownParams ) {
			return (
				<a
					href="#"
					onClick={( e ) => {
						e.preventDefault();
						onDrilldown( drilldownParams );
					}}
					title={__( 'Show items', 'adpresso' )}
				>
					{content}
					<span className="adpresso-text adpresso-color-grey"> (ID: {rowId})</span>
				</a>
			);
		}

		return (
			<>
				{content}
				{row.ad_id && <span className="adpresso-text adpresso-color-grey"> (ID: {row.ad_id})</span>}
			</>
		);
	};

	const compareMap = useMemo( () => {
		if ( !compareData ) {
			return new Map();
		}

		const map = new Map();
		// Bestimme den Schlüssel (date, ad_id, group_id, etc.)
		const keyName = viewMode === 'date' ? 'date' : (viewMode.slice( 0, - 1 ) + '_id');

		compareData.forEach( row => {
			map.set( row[keyName], row );
		} );
		return map;
	}, [compareData, viewMode] );

	return (
		<table className="wp-list-table table-view-list adpresso-data-table">
			<thead>
			<tr>
				{viewMode === 'date' ? (
					<SortableHeader label={getFirstColumnHeader()} columnKey="date"/>
				) : (
					<SortableHeader label={getFirstColumnHeader()} columnKey="name"/>
				)}
				{showCol( 'impressions' ) && <SortableHeader label={__( 'Impressions', 'adpresso' )} columnKey="impressions"/>}
				{showCol( 'clicks' ) && <SortableHeader label={__( 'Clicks', 'adpresso' )} columnKey="clicks"/>}
				{showCol( 'ctr' ) && <SortableHeader label={__( 'CTR (%)', 'adpresso' )} columnKey="ctr"/>}
				{isPro && showCol( 'viewability' ) && <SortableHeader label={__( 'Active View Rate (%)', 'adpresso' )} columnKey="viewability"/>}
				{isPro && showCol( 'impressions_av' ) && <SortableHeader label={__( 'Active View Impressions', 'adpresso' )} columnKey="impressions_av"/>}
			</tr>
			</thead>
			<tbody>
			{tableData.length === 0 && (
				<tr>
					<td colSpan={getVisibleColumnCount()} style={{textAlign: 'center'}}>
						{__( 'No data to display.', 'adpresso' )}
					</td>
				</tr>
			)}
			{tableData.map( ( row, index ) => {
				const keyName = viewMode === 'date' ? 'date' : (viewMode.slice( 0, - 1 ) + '_id');
				const rowKey = row[keyName];

				const compareRow = compareMap.get( rowKey ) || {};

				const metricsA = {
					impressions:    row.impressions || 0,
					impressions_av: row.impressions_av || 0,
					clicks:         row.clicks || 0,
					ctr:            row.ctr || 0,
					viewability:    row.viewability || 0
				};
				const metricsB = {
					impressions:    compareRow.impressions || 0,
					impressions_av: compareRow.impressions_av || 0,
					clicks:         compareRow.clicks || 0,
					ctr:            compareRow.ctr || 0,
					viewability:    compareRow.viewability || 0
				};

				return (
					<tr key={rowKey || index}>
						<td>{renderFirstColumn( row )}</td>
						{compareData ? (
							// COMPARE VIEW
							<>
								{showCol( 'impressions' ) && <td><CompareCell metricA={metricsA.impressions} metricB={metricsB.impressions} format={formatNumber}/></td>}
								{showCol( 'impressions_av' ) && <td><CompareCell metricA={metricsA.impressions_av} metricB={metricsB.impressions_av} format={formatNumber}/></td>}
								{showCol( 'clicks' ) && <td><CompareCell metricA={metricsA.clicks} metricB={metricsB.clicks} format={formatNumber}/></td>}
								{showCol( 'ctr' ) && <td><CompareCell metricA={metricsA.ctr} metricB={metricsB.ctr} format={formatPercent}/></td>}
								{showCol( 'viewability' ) && <td><CompareCell metricA={metricsA.viewability} metricB={metricsB.viewability} format={formatPercent}/></td>}
							</>
						) : (
							// STANDARD VIEW (Free)
							<>
								{showCol( 'impressions' ) && <td>{formatNumber( metricsA.impressions )}</td>}
								{showCol( 'impressions_av' ) && <td>{formatNumber( metricsA.impressions_av )}</td>}
								{showCol( 'clicks' ) && <td>{formatNumber( metricsA.clicks )}</td>}
								{showCol( 'ctr' ) && <td>{formatPercent( metricsA.ctr )}</td>}
								{showCol( 'viewability' ) && <td>{formatPercent( metricsA.viewability )}</td>}
							</>
						)}
					</tr>
				);
			} )}
			</tbody>
		</table>
	);
};

export default DataTable;
