<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class AIEO_DMM_UTM_Explorer extends AIEO_DMM_Module_Base {

	const NONCE = 'aieo_utm_explorer';
	const CAP   = 'manage_woocommerce';

	
	const LEVELS = array(
		'channel'  => 'ordersource',
		'source'   => 'orderutmsource',
		'medium'   => 'orderutmmedium',
		'campaign' => 'orderutmcampaign',
		'term'     => 'orderutmterm',
		'content'  => 'orderutmcontent',
	);

	
	const ORDER  = array( 'channel', 'source', 'medium', 'campaign', 'term', 'content' );

	
	const LABELS = array(
		'channel'  => 'Channel',
		'source'   => 'Source',
		'medium'   => 'Medium',
		'campaign' => 'Campaign',
		'term'     => 'Term',
		'content'  => 'Content',
	);

	public function get_id() {
		return 'utm_explorer';
	}

	public function get_label() {
		return __( 'UTM Explorer', 'ai-eshop-optimizer' );
	}

	public function get_group() {
		return 'attribution';
	}

	public function get_priority() {
		return 16;
	}

	public function register_hooks() {
		add_action( 'wp_ajax_aieo_utm_explore', array( $this, 'ajax_explore' ) );
		add_action( 'wp_ajax_aieo_utm_search', array( $this, 'ajax_search' ) );
	}

	

	private function guard() {
		check_ajax_referer( self::NONCE, 'nonce' );
		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'msg' => 'forbidden' ), 403 );
		}
	}

	
	private function dates() {
		$to   = isset( $_REQUEST['to'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['to'] ) ) : '';
		$from = isset( $_REQUEST['from'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['from'] ) ) : '';
		$d    = '/^\d{4}-\d{2}-\d{2}$/';
		if ( ! preg_match( $d, $to ) ) {
			$to = gmdate( 'Y-m-d' );
		}
		if ( ! preg_match( $d, $from ) ) {
			$from = gmdate( 'Y-m-d', strtotime( $to . ' -30 days' ) );
		}
		return array( $from, $to );
	}

	
	private function compare_dates( $from, $to, $mode ) {
		if ( 'prev' === $mode ) {
			$days = (int) round( ( strtotime( $to ) - strtotime( $from ) ) / 86400 ) + 1;
			return array( gmdate( 'Y-m-d', strtotime( $from . ' -' . $days . ' days' ) ), gmdate( 'Y-m-d', strtotime( $from . ' -1 day' ) ) );
		}
		if ( 'yoy' === $mode ) {
			return array( gmdate( 'Y-m-d', strtotime( $from . ' -1 year' ) ), gmdate( 'Y-m-d', strtotime( $to . ' -1 year' ) ) );
		}
		return array( '', '' );
	}

	
	private function selection() {
		$sel = array();
		foreach ( self::ORDER as $lvl ) {
			$sel[ $lvl ] = isset( $_REQUEST[ $lvl ] )
				? array_values( array_filter( array_map( 'sanitize_text_field', (array) wp_unslash( $_REQUEST[ $lvl ] ) ), 'strlen' ) )
				: array();
		}
		return $sel;
	}

	
	private function where_and_args( $sel, $consider, $from, $to ) {
		$w    = 'orderdate >= %s AND orderdate <= %s';
		$args = array( $from, $to );
		foreach ( $consider as $lvl ) {
			$vals = isset( $sel[ $lvl ] ) ? (array) $sel[ $lvl ] : array();
			if ( ! empty( $vals ) ) {
				$w     .= ' AND `' . self::LEVELS[ $lvl ] . '` IN (' . implode( ',', array_fill( 0, count( $vals ), '%s' ) ) . ')';
				$args   = array_merge( $args, array_values( $vals ) );
			}
		}
		return array( $w, $args );
	}

	

	public function ajax_search() {
		$this->guard();
		global $wpdb;
		$st    = $wpdb->prefix . 'aieo_order_stats';
		$level = isset( $_REQUEST['level'] ) ? sanitize_key( $_REQUEST['level'] ) : '';
		if ( ! isset( self::LEVELS[ $level ] ) ) {
			wp_send_json( array( 'results' => array() ) );
		}
		$q   = isset( $_REQUEST['q'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['q'] ) ) : '';
		$sel = $this->selection();

		
		
		
		
		$idx       = array_search( $level, self::ORDER, true );
		$ancestors = array_slice( self::ORDER, 0, $idx );
		$w    = '1=1';
		$args = array();
		foreach ( $ancestors as $alvl ) {
			$avals = isset( $sel[ $alvl ] ) ? (array) $sel[ $alvl ] : array();
			if ( ! empty( $avals ) ) {
				$w     .= ' AND `' . self::LEVELS[ $alvl ] . '` IN (' . implode( ',', array_fill( 0, count( $avals ), '%s' ) ) . ')';
				$args   = array_merge( $args, array_values( $avals ) );
			}
		}
		$col   = self::LEVELS[ $level ];
		$w    .= " AND `{$col}` IS NOT NULL AND `{$col}` <> '' AND `{$col}` LIKE %s";
		$args[] = '%' . $wpdb->esc_like( $q ) . '%';

		$vals = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT `{$col}` FROM {$st} WHERE {$w} ORDER BY `{$col}` LIMIT 200", $args ) );
		$out  = array();
		foreach ( (array) $vals as $v ) {
			$out[] = array( 'value' => (string) $v, 'label' => (string) $v );
		}
		wp_send_json( array( 'results' => $out ) );
	}

	
	private function breakdown_expr( $drill ) {
		$col = '`' . self::LEVELS[ $drill ] . '`';
		if ( ! in_array( $drill, array( 'channel', 'source' ), true ) ) {
			return $col;
		}
		return "CASE {$col}
			WHEN 'paid_google'      THEN 'Google - Paid'
			WHEN 'paid_fb'          THEN 'Facebook - Paid'
			WHEN 'paid_fb-sitelink' THEN 'Facebook - Paid'
			WHEN 'paid_facebook'    THEN 'Facebook - Paid'
			WHEN 'paid_microsoft'   THEN 'Microsoft - Paid'
			WHEN 'paid_other'       THEN 'Paid - Other'
			WHEN 'organic'          THEN 'Organic Search'
			WHEN 'organic_search'   THEN 'Organic Search'
			WHEN 'google'           THEN 'Organic Search'
			WHEN 'direct'           THEN 'Direct'
			WHEN '(direct)'         THEN 'Direct'
			WHEN 'referral'         THEN 'Referral'
			WHEN 'social'           THEN 'Social'
			WHEN 'ig'               THEN 'Instagram'
			WHEN 'fb'               THEN 'Facebook'
			WHEN 'newsletter'       THEN 'Newsletter'
			WHEN 'aieo_push'        THEN 'Push notification'
			WHEN 'skroutz'          THEN 'Skroutz'
			WHEN 'shopflix'         THEN 'Shopflix'
			ELSE {$col}
		END";
	}

	

	public function ajax_explore() {
		$this->guard();
		global $wpdb;
		$st  = $wpdb->prefix . 'aieo_order_stats';
		$sel = $this->selection();
		list( $from, $to ) = $this->dates();

		
		$drill = null;
		foreach ( self::ORDER as $lvl ) {
			if ( empty( $sel[ $lvl ] ) ) {
				$drill = $lvl;
				break;
			}
		}
		list( $w, $args ) = $this->where_and_args( $sel, self::ORDER, $from, $to );

		$rows = array();
		if ( null !== $drill ) {
			$expr = $this->breakdown_expr( $drill );
			$res  = $wpdb->get_results( $wpdb->prepare(
				"SELECT {$expr} AS label, COUNT(*) AS orders, COALESCE(SUM(orderspend),0) AS revenue
				 FROM {$st} WHERE {$w} GROUP BY {$expr} ORDER BY revenue DESC LIMIT 300",
				$args
			) );
			foreach ( (array) $res as $r ) {
				$o   = (int) $r->orders;
				$rev = (float) $r->revenue;
				$rows[] = array(
					'label'   => ( '' === (string) $r->label ) ? '(none)' : (string) $r->label,
					'orders'  => $o,
					'revenue' => round( $rev, 2 ),
					'aov'     => $o > 0 ? round( $rev / $o, 2 ) : 0.0,
				);
			}
		}

		$tot = $wpdb->get_row( $wpdb->prepare(
			"SELECT COUNT(*) AS orders, COALESCE(SUM(orderspend),0) AS revenue FROM {$st} WHERE {$w}",
			$args
		) );

		$total = array(
			'orders'  => (int) ( $tot->orders ?? 0 ),
			'revenue' => round( (float) ( $tot->revenue ?? 0 ), 2 ),
		);

		
		$compare = isset( $_REQUEST['compare'] ) ? sanitize_key( wp_unslash( $_REQUEST['compare'] ) ) : '';
		$cfrom   = '';
		$cto     = '';
		if ( in_array( $compare, array( 'prev', 'yoy' ), true ) ) {
			list( $cfrom, $cto ) = $this->compare_dates( $from, $to, $compare );
			list( $cw, $cargs )  = $this->where_and_args( $sel, self::ORDER, $cfrom, $cto );
			$ct  = $wpdb->get_row( $wpdb->prepare( "SELECT COUNT(*) AS orders, COALESCE(SUM(orderspend),0) AS revenue FROM {$st} WHERE {$cw}", $cargs ) );
			$pco = (int) ( $ct->orders ?? 0 );
			$pcr = (float) ( $ct->revenue ?? 0 );
			$total['d_orders']  = $pco > 0 ? round( 100 * ( $total['orders'] - $pco ) / $pco, 1 ) : null;
			$total['d_revenue'] = $pcr > 0 ? round( 100 * ( $total['revenue'] - $pcr ) / $pcr, 1 ) : null;
			if ( null !== $drill ) {
				$expr = $this->breakdown_expr( $drill );
				$cmap = array();
				foreach ( (array) $wpdb->get_results( $wpdb->prepare( "SELECT {$expr} AS label, COUNT(*) AS orders, COALESCE(SUM(orderspend),0) AS revenue FROM {$st} WHERE {$cw} GROUP BY {$expr}", $cargs ) ) as $cr ) {
					$cmap[ ( '' === (string) $cr->label ) ? '(none)' : (string) $cr->label ] = $cr;
				}
				foreach ( $rows as $ri => $r ) {
					$c   = isset( $cmap[ $r['label'] ] ) ? $cmap[ $r['label'] ] : null;
					$pco = $c ? (int) $c->orders : 0;
					$pcr = $c ? (float) $c->revenue : 0.0;
					$rows[ $ri ]['d_orders']  = $pco > 0 ? round( 100 * ( $r['orders'] - $pco ) / $pco, 1 ) : null;
					$rows[ $ri ]['d_revenue'] = $pcr > 0 ? round( 100 * ( $r['revenue'] - $pcr ) / $pcr, 1 ) : null;
				}
			}
		}

		wp_send_json_success( array(
			'drill'       => $drill,
			'drill_label' => $drill ? self::LABELS[ $drill ] : '',
			'rows'        => $rows,
			'total'       => $total,
			'from'        => $from,
			'to'          => $to,
			'compare'     => $compare,
			'cfrom'       => $cfrom,
			'cto'         => $cto,
		) );
	}

	

	public function render_subtab() {
		$nonce    = wp_create_nonce( self::NONCE );
		$def_from = gmdate( 'Y-m-d', strtotime( '-30 days' ) );
		$def_to   = gmdate( 'Y-m-d' );
		if ( defined( 'AIEO_FILE' ) ) {
			$vp_abs = dirname( AIEO_FILE ) . '/assets/js/aieo-value-picker.js';
			wp_enqueue_script( 'aieo-value-picker', plugins_url( 'assets/js/aieo-value-picker.js', AIEO_FILE ), array(), is_readable( $vp_abs ) ? (string) filemtime( $vp_abs ) : '1', true );
		}
		$ajaxurl = esc_attr( admin_url( 'admin-ajax.php' ) );

		echo '<div class="aieo-dmm-section">';
		echo '<div class="aieo-dmm-card">';
		echo '<h3>' . esc_html__( 'UTM Explorer', 'ai-eshop-optimizer' ) . '</h3>';
		echo '<p style="opacity:.8;margin-top:0;max-width:820px">'
			. esc_html__( 'A stepped drill-down across the five campaign tags. Each is a searchable multi-select — pick any mix of Sources and the lists below narrow to what occurred under them, then Medium, Campaign, Term, Content. The table breaks your current selection down by the next level, with orders, revenue and average order value.', 'ai-eshop-optimizer' )
			. '</p>';

		echo '<div style="display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start;margin:14px 0">';
		foreach ( self::ORDER as $i => $lvl ) {
			$ctx = array( 'from:aieo-utm-from', 'to:aieo-utm-to' );
			foreach ( array_slice( self::ORDER, 0, $i ) as $anc ) {
				$ctx[] = $anc . ':aieo-utm-' . $anc;
			}
			$lvl_suffix = ( 'channel' === $lvl ) ? __( 'resolved', 'ai-eshop-optimizer' ) : 'utm_' . $lvl;
			echo '<label>' . esc_html( self::LABELS[ $lvl ] )
				. ' <span style="opacity:.5">(' . esc_html( $lvl_suffix ) . ')</span><br>'
				. '<span class="aieo-valpick" id="aieo-utm-' . esc_attr( $lvl ) . '" data-search-action="aieo_utm_search"'
				. ' data-params="level=' . esc_attr( $lvl ) . '" data-multi="1"'
				. ' data-title="' . esc_attr( sprintf(  __( 'Choose %s values', 'ai-eshop-optimizer' ), self::LABELS[ $lvl ] ) ) . '"'
				. ' data-placeholder="' . esc_attr__( 'Search…', 'ai-eshop-optimizer' ) . '" data-empty="' . esc_attr__( '— all —', 'ai-eshop-optimizer' ) . '"'
				. ' data-context="' . esc_attr( implode( ',', $ctx ) ) . '"'
				. ' data-ajaxurl="' . $ajaxurl . '" data-nonce="' . esc_attr( $nonce ) . '">'
				. '<input type="hidden" class="aieo-valpick-store" value="">'
				. '<button type="button" class="button aieo-valpick-open">' . esc_html__( '— all —', 'ai-eshop-optimizer' ) . '</button>'
				. '<span class="aieo-valpick-chips"></span>'
				. '</span></label>';
		}
		echo '<label>' . esc_html__( 'Compare', 'ai-eshop-optimizer' ) . '<br><select id="aieo-utm-compare">'
			. '<option value="">' . esc_html__( '— off —', 'ai-eshop-optimizer' ) . '</option>'
			. '<option value="prev">' . esc_html__( 'Previous period', 'ai-eshop-optimizer' ) . '</option>'
			. '<option value="yoy">' . esc_html__( 'Same period last year', 'ai-eshop-optimizer' ) . '</option>'
			. '</select></label>';
		echo '<label style="order:-2">' . esc_html__( 'From', 'ai-eshop-optimizer' ) . '<br><input type="date" id="aieo-utm-from" value="' . esc_attr( $def_from ) . '"></label>';
		echo '<label style="order:-1">' . esc_html__( 'To', 'ai-eshop-optimizer' ) . '<br><input type="date" id="aieo-utm-to" value="' . esc_attr( $def_to ) . '"></label>';
		echo '<span>&nbsp;<br><button type="button" class="button" id="aieo-utm-reset">' . esc_html__( 'Reset', 'ai-eshop-optimizer' ) . '</button></span>';
		echo '</div>';

		echo '<div id="aieo-utm-results" style="margin-top:8px"></div>';
		echo '</div>'; 
		echo '</div>'; 

		$this->print_js( $nonce );
	}

	private function print_js( $nonce ) {
		$ajax   = admin_url( 'admin-ajax.php' );
		$labels = array();
		foreach ( self::ORDER as $l ) {
			$labels[ $l ] = self::LABELS[ $l ];
		}
		?>
		<script>
		(function () {
			var AJAX = <?php echo wp_json_encode( $ajax ); ?>, NONCE = <?php echo wp_json_encode( $nonce ); ?>;
			var ORDER = <?php echo wp_json_encode( array_values( self::ORDER ) ); ?>, LABELS = <?php echo wp_json_encode( $labels ); ?>;
			function $(id){ return document.getElementById(id); }
			function post(action, data){ data=data||{}; data.action=action; data.nonce=NONCE; var fd=new FormData(); for(var k in data){ var v=data[k]; if(Array.isArray(v)){ v.forEach(function(x){ fd.append(k+'[]', x); }); } else { fd.append(k, v); } } return fetch(AJAX,{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();}); }
			function money(n){ return (n==null?'—':(Math.round(n*100)/100).toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2})+' €'); }
			function esc(s){ var d=document.createElement('div'); d.textContent=(s==null?'':s); return d.innerHTML; }
			function dpct(d){ if(d==null){ return ''; } return ' <span style="font-size:11px;font-weight:600;color:'+(d>=0?'#1a7f37':'#c0392b')+'">'+(d>=0?'+':'')+d+'%</span>'; }
			function vals(l){ return window.aieoValPicker ? aieoValPicker.values($('aieo-utm-'+l)) : []; }
			function explore(){
				var data={from:$('aieo-utm-from').value,to:$('aieo-utm-to').value};
				ORDER.forEach(function(l){ data[l]=vals(l); });
				data.compare=($('aieo-utm-compare')?$('aieo-utm-compare').value:'');
				$('aieo-utm-results').innerHTML='<p style="opacity:.6">…</p>';
				post('aieo_utm_explore', data).then(function(j){
					if(!j||!j.success){ $('aieo-utm-results').innerHTML='<p>Error.</p>'; return; }
					var d=j.data;
					var crumbs=[]; ORDER.forEach(function(l){ var vv=vals(l); if(vv.length){ crumbs.push(LABELS[l]+': '+vv.join(' / ')); } });
					var bc = crumbs.length ? crumbs.join(' › ') : '<?php echo esc_js( __( 'All traffic', 'ai-eshop-optimizer' ) ); ?>';
					var h='<p style="margin:6px 0"><strong>'+esc(bc)+'</strong> — '+d.total.orders+dpct(d.total.d_orders)+' orders, '+money(d.total.revenue)+dpct(d.total.d_revenue)+(d.compare&&d.cfrom?' <span style="opacity:.7;font-weight:400">(Δ% vs '+d.cfrom+' → '+d.cto+', '+(d.compare==="yoy"?"same period last year":"previous period")+')</span>':'')+'</p>';
					if(d.drill && d.rows.length){
						h+='<table class="widefat striped" style="margin-top:6px"><thead><tr><th>'+esc(d.drill_label)+'</th><th>Orders</th><th>Revenue</th><th>Avg order</th></tr></thead><tbody>';
						d.rows.forEach(function(r){ h+='<tr><td>'+esc(r.label)+'</td><td>'+r.orders+dpct(r.d_orders)+'</td><td>'+money(r.revenue)+dpct(r.d_revenue)+'</td><td>'+money(r.aov)+'</td></tr>'; });
						h+='</tbody><tfoot><tr style="font-weight:700;background:#f6f7f7;border-top:2px solid #c3c4c7"><td>Total</td><td>'+d.total.orders+'</td><td>'+money(d.total.revenue)+'</td><td>'+money(d.total.orders>0?d.total.revenue/d.total.orders:0)+'</td></tr></tfoot></table><p style="opacity:.6;margin-top:6px">Broken down by '+esc(d.drill_label)+'. Pick value(s) above to drill deeper. Period '+d.from+' → '+d.to+'.</p>';
					} else if(!d.drill){
						h+='<p style="opacity:.7">Every level is filtered — '+d.total.orders+' orders.</p>';
					} else {
						h+='<p style="opacity:.7">No data for this selection / period.</p>';
					}
					$('aieo-utm-results').innerHTML=h;
				});
			}
			// Changing a level invalidates its descendants → clear them (suppressing
			// the cascade of change events), then explore once.
			var suppress=false;
			ORDER.forEach(function(l, i){
				var w=$('aieo-utm-'+l);
				if(!w){ return; }
				w.addEventListener('aieo-valpick:change', function(){
					if(suppress){ return; }
					suppress=true;
					for(var k=i+1;k<ORDER.length;k++){ if(window.aieoValPicker){ aieoValPicker.clear($('aieo-utm-'+ORDER[k])); } }
					suppress=false;
					explore();
				});
			});
			$('aieo-utm-from').addEventListener('change', explore);
			$('aieo-utm-to').addEventListener('change', explore);
			$('aieo-utm-reset').addEventListener('click', function(){ suppress=true; ORDER.forEach(function(l){ if(window.aieoValPicker){ aieoValPicker.clear($('aieo-utm-'+l)); } }); suppress=false; explore(); });
			explore();
		})();
		</script>
		<?php
	}
}
