<?php
/**
 * Export Statistics & Analytics Service.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Modules\Exports\Service;

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

final class ExportStatisticsService {

    /**
     * Get comprehensive statistics for all exports.
     *
     * @param array $args {
     *     Optional. Arguments for filtering statistics.
     *     @type string $date_from Start date (Y-m-d format).
     *     @type string $date_to   End date (Y-m-d format).
     *     @type int    $export_id Specific export ID.
     *     @type string $type     Export type filter (products, orders, customers, coupons).
     * }
     * @return array
     */
    public static function get_statistics( $args = array() ) {
        $defaults = array(
            'date_from' => '',
            'date_to'   => '',
            'export_id' => 0,
            'type'      => '',
        );
        $args = wp_parse_args( $args, $defaults );

        $drafts = get_option( 'mt_primelink_export_drafts', array() );
        $drafts = is_array( $drafts ) ? $drafts : array();

        $stats = array(
            'overview'         => self::get_overview_stats( $drafts, $args ),
            'by_status'        => self::get_stats_by_status( $drafts, $args ),
            'by_type'          => self::get_stats_by_type( $drafts, $args ),
            'timeline'         => self::get_timeline_stats( $drafts, $args ),
            'performance'      => self::get_performance_stats( $drafts, $args ),
            'top_exports'      => self::get_top_exports( $drafts, $args ),
            'recent_activity'  => self::get_recent_activity( $drafts, $args ),
        );

        return $stats;
    }

    /**
     * Get overview statistics.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_overview_stats( $drafts, $args ) {
        $total_exports = 0;
        $total_exported = 0;
        $total_errors  = 0;
        $total_runtime = 0;

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $state = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            if ( empty( $state ) ) {
                continue;
            }

            $total_exports++;
            $total_exported += absint( $state['exported'] ?? $state['current'] ?? 0 );
            $total_errors   += absint( $state['errors'] ?? 0 );

            // Calculate runtime if available
            if ( ! empty( $state['started_at'] ) && ! empty( $state['finished_at'] ) ) {
                $start = strtotime( $state['started_at'] );
                $end   = strtotime( $state['finished_at'] );
                if ( $start && $end && $end > $start ) {
                    $total_runtime += ( $end - $start );
                }
            }
        }

        return array(
            'total_exports'  => $total_exports,
            'total_exported' => $total_exported,
            'total_errors'   => $total_errors,
            'total_runtime'  => $total_runtime,
            'avg_runtime'    => $total_exports > 0 ? round( $total_runtime / $total_exports ) : 0,
            'success_rate'  => $total_exported > 0
                ? round( ( $total_exported / ( $total_exported + $total_errors ) ) * 100, 2 )
                : 0,
        );
    }

    /**
     * Get statistics grouped by status.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_stats_by_status( $drafts, $args ) {
        $statuses = array(
            'idle'     => 0,
            'running'  => 0,
            'paused'   => 0,
            'completed' => 0,
            'error'    => 0,
        );

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $state  = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            $status = $state['status'] ?? 'idle';
            if ( isset( $statuses[ $status ] ) ) {
                $statuses[ $status ]++;
            }
        }

        return $statuses;
    }

    /**
     * Get statistics grouped by export type.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_stats_by_type( $drafts, $args ) {
        $types = array();

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $type = $draft['type'] ?? ( $draft['step_data'][1]['type'] ?? 'product' );
            if ( ! isset( $types[ $type ] ) ) {
                $types[ $type ] = 0;
            }
            $types[ $type ]++;
        }

        return $types;
    }

    /**
     * Get timeline statistics.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_timeline_stats( $drafts, $args ) {
        $timeline = array();

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $created_at = $draft['created_at'] ?? '';
            if ( empty( $created_at ) ) {
                continue;
            }

            $date = date( 'Y-m-d', strtotime( $created_at ) );
            if ( ! $date ) {
                continue;
            }

            if ( ! isset( $timeline[ $date ] ) ) {
                $timeline[ $date ] = array(
                    'date'    => $date,
                    'count'   => 0,
                    'exported' => 0,
                    'errors'  => 0,
                );
            }

            $timeline[ $date ]['count']++;

            $state = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            if ( ! empty( $state ) ) {
                $timeline[ $date ]['exported'] += absint( $state['exported'] ?? $state['current'] ?? 0 );
                $timeline[ $date ]['errors']   += absint( $state['errors'] ?? 0 );
            }
        }

        // Sort by date
        ksort( $timeline );

        return array_values( $timeline );
    }

    /**
     * Get performance statistics.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_performance_stats( $drafts, $args ) {
        $runtimes = array();
        $speeds   = array();

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $state = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            if ( empty( $state ) || empty( $state['started_at'] ) ) {
                continue;
            }

            $start = strtotime( $state['started_at'] );
            $end   = ! empty( $state['finished_at'] ) ? strtotime( $state['finished_at'] ) : time();

            if ( ! $start || ! $end || $end <= $start ) {
                continue;
            }

            $runtime = $end - $start;
            $total   = absint( $state['total'] ?? 0 );
            $processed = absint( $state['current'] ?? 0 );

            if ( $total > 0 && $runtime > 0 ) {
                $speed = $processed / $runtime; // items per second
                $speeds[] = $speed;
            }

            $runtimes[] = $runtime;
        }

        return array(
            'avg_runtime'     => ! empty( $runtimes ) ? round( array_sum( $runtimes ) / count( $runtimes ) ) : 0,
            'total_runtime'   => array_sum( $runtimes ),
            'min_runtime'     => ! empty( $runtimes ) ? min( $runtimes ) : 0,
            'max_runtime'     => ! empty( $runtimes ) ? max( $runtimes ) : 0,
            'avg_speed'       => ! empty( $speeds ) ? round( array_sum( $speeds ) / count( $speeds ), 2 ) : 0,
        );
    }

    /**
     * Get top exports.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_top_exports( $drafts, $args ) {
        $exports = array();

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $state = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            if ( empty( $state ) ) {
                continue;
            }

            $exported = absint( $state['exported'] ?? $state['current'] ?? 0 );
            if ( $exported < 1 ) {
                continue;
            }

            $exports[] = array(
                'id'       => $id,
                'type'     => $draft['type'] ?? ( $draft['step_data'][1]['type'] ?? 'product' ),
                'exported' => $exported,
                'errors'   => absint( $state['errors'] ?? 0 ),
                'status'   => $state['status'] ?? 'idle',
            );
        }

        // Sort by exported count (descending)
        usort( $exports, function( $a, $b ) {
            return ( $b['exported'] ?? 0 ) <=> ( $a['exported'] ?? 0 );
        } );

        return array_slice( $exports, 0, 10 );
    }

    /**
     * Get recent activity.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_recent_activity( $drafts, $args ) {
        $activity = array();

        $filtered = self::filter_drafts( $drafts, $args );

        foreach ( $filtered as $id => $draft ) {
            $state = get_option( 'mt_primelink_export_state_' . absint( $id ), array() );
            if ( empty( $state ) ) {
                continue;
            }

            $last_update = $state['finished_at'] ?? $state['started_at'] ?? $draft['created_at'] ?? '';
            if ( empty( $last_update ) ) {
                continue;
            }

            $activity[] = array(
                'id'          => $id,
                'type'        => $draft['type'] ?? ( $draft['step_data'][1]['type'] ?? 'product' ),
                'status'      => $state['status'] ?? 'idle',
                'exported'     => absint( $state['exported'] ?? $state['current'] ?? 0 ),
                'errors'      => absint( $state['errors'] ?? 0 ),
                'last_update' => $last_update,
                'timestamp'   => strtotime( $last_update ),
            );
        }

        // Sort by timestamp (most recent first)
        usort( $activity, function( $a, $b ) {
            return ( $b['timestamp'] ?? 0 ) <=> ( $a['timestamp'] ?? 0 );
        } );

        return array_slice( $activity, 0, 20 );
    }

    /**
     * Filter drafts based on arguments.
     *
     * @param array $drafts All export drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function filter_drafts( $drafts, $args ) {
        $filtered = $drafts;

        // Filter by export_id
        if ( ! empty( $args['export_id'] ) ) {
            $export_id = absint( $args['export_id'] );
            if ( isset( $filtered[ $export_id ] ) ) {
                $filtered = array( $export_id => $filtered[ $export_id ] );
            } else {
                return array();
            }
        }

        // Filter by type
        if ( ! empty( $args['type'] ) ) {
            $type = sanitize_text_field( $args['type'] );
            $filtered = array_filter( $filtered, function( $draft ) use ( $type ) {
                $draft_type = $draft['type'] ?? ( $draft['step_data'][1]['type'] ?? 'product' );
                return $draft_type === $type;
            } );
        }

        // Filter by date range
        if ( ! empty( $args['date_from'] ) || ! empty( $args['date_to'] ) ) {
            $date_from = ! empty( $args['date_from'] ) ? strtotime( $args['date_from'] ) : 0;
            $date_to   = ! empty( $args['date_to'] ) ? strtotime( $args['date_to'] . ' 23:59:59' ) : time();

            $filtered = array_filter( $filtered, function( $draft ) use ( $date_from, $date_to ) {
                $created_at = $draft['created_at'] ?? '';
                if ( empty( $created_at ) ) {
                    return false;
                }
                $timestamp = strtotime( $created_at );
                if ( ! $timestamp ) {
                    return false;
                }
                if ( $date_from > 0 && $timestamp < $date_from ) {
                    return false;
                }
                if ( $date_to > 0 && $timestamp > $date_to ) {
                    return false;
                }
                return true;
            } );
        }

        return $filtered;
    }
}





