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

namespace PrimeLink\Modules\Imports\Service;

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

final class StatisticsService {

    /**
     * Get comprehensive statistics for all imports.
     *
     * @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    $import_id Specific import ID.
     * }
     * @return array
     */
    public static function get_statistics( $args = array() ) {
        $defaults = array(
            'date_from' => '',
            'date_to'   => '',
            'import_id' => 0,
            'type'      => '',
        );
        $args = wp_parse_args( $args, $defaults );

        $drafts = get_option( 'mt_primelink_import_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_imports'       => self::get_top_imports( $drafts, $args ),
            'recent_activity'   => self::get_recent_activity( $drafts, $args ),
        );

        return $stats;
    }

    /**
     * Get overview statistics.
     *
     * @param array $drafts All import drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_overview_stats( $drafts, $args ) {
        $total_imports = 0;
        $total_created = 0;
        $total_updated = 0;
        $total_skipped = 0;
        $total_errors  = 0;
        $total_runtime = 0;

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

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

            $total_imports++;
            $total_created += absint( $state['created'] ?? 0 );
            $total_updated += absint( $state['updated'] ?? 0 );
            $total_skipped += absint( $state['skipped'] ?? 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_imports'  => $total_imports,
            'total_created'  => $total_created,
            'total_updated'  => $total_updated,
            'total_skipped'  => $total_skipped,
            'total_errors'   => $total_errors,
            'total_runtime'  => $total_runtime,
            'avg_runtime'    => $total_imports > 0 ? round( $total_runtime / $total_imports ) : 0,
            'success_rate'  => ( $total_created + $total_updated ) > 0
                ? round( ( ( $total_created + $total_updated ) / ( $total_created + $total_updated + $total_errors ) ) * 100, 2 )
                : 0,
        );
    }

    /**
     * Get statistics grouped by status.
     *
     * @param array $drafts All import 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,
            'finished' => 0,
            'error'    => 0,
        );

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

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

        return $statuses;
    }

    /**
     * Get statistics grouped by import type.
     *
     * @param array $drafts All import 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 ] = array(
                    'count'   => 0,
                    'created' => 0,
                    'updated' => 0,
                    'errors'  => 0,
                );
            }
            $types[ $type ]['count']++;

            $state = get_option( 'mt_primelink_import_state_' . absint( $id ), array() );
            if ( ! empty( $state ) ) {
                $types[ $type ]['created'] += absint( $state['created'] ?? 0 );
                $types[ $type ]['updated'] += absint( $state['updated'] ?? 0 );
                $types[ $type ]['errors']  += absint( $state['errors'] ?? 0 );
            }
        }

        return $types;
    }

    /**
     * Get timeline statistics (daily/weekly/monthly).
     *
     * @param array $drafts All import 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,
                    'created' => 0,
                    'updated' => 0,
                    'errors'  => 0,
                );
            }

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

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

        // Sort by date
        ksort( $timeline );

        return array_values( $timeline );
    }

    /**
     * Get performance statistics.
     *
     * @param array $drafts All import 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_import_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,
            'min_runtime'     => ! empty( $runtimes ) ? min( $runtimes ) : 0,
            'max_runtime'     => ! empty( $runtimes ) ? max( $runtimes ) : 0,
            'avg_speed'       => ! empty( $speeds ) ? round( array_sum( $speeds ), 2 ) : 0,
            'total_runtime'   => array_sum( $runtimes ),
        );
    }

    /**
     * Get top imports by various metrics.
     *
     * @param array $drafts All import drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function get_top_imports( $drafts, $args ) {
        $imports = array();

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

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

            $imports[] = array(
                'id'       => $id,
                'type'     => $draft['type'] ?? ( $draft['step_data'][1]['type'] ?? 'product' ),
                'created'  => absint( $state['created'] ?? 0 ),
                'updated'  => absint( $state['updated'] ?? 0 ),
                'errors'   => absint( $state['errors'] ?? 0 ),
                'total'    => absint( $state['total'] ?? 0 ),
                'status'   => $state['status'] ?? 'idle',
                'created_at' => $draft['created_at'] ?? '',
            );
        }

        // Sort by total created + updated
        usort( $imports, function( $a, $b ) {
            $a_total = $a['created'] + $a['updated'];
            $b_total = $b['created'] + $b['updated'];
            return $b_total <=> $a_total;
        } );

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

    /**
     * Get recent activity.
     *
     * @param array $drafts All import 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_import_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',
                'created'     => absint( $state['created'] ?? 0 ),
                'updated'     => absint( $state['updated'] ?? 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 import drafts.
     * @param array $args   Filter arguments.
     * @return array
     */
    private static function filter_drafts( $drafts, $args ) {
        $filtered = $drafts;

        // Filter by import_id
        if ( ! empty( $args['import_id'] ) ) {
            $import_id = absint( $args['import_id'] );
            if ( isset( $filtered[ $import_id ] ) ) {
                $filtered = array( $import_id => $filtered[ $import_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;
    }
}



