<?php
namespace WPEventGenius\Common\Series;

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

class RecurrencePattern {
    protected $type;
    protected $interval;
    protected $start_date;  // Local time
    protected $end_date;    // Local time
    protected $timezone;
    protected $days = array();

    /**
     * Local calendar dates (Y-m-d) to omit from the series — same source as post meta evge_recurrence_skip_dates.
     *
     * @var list<string>
     */
    protected $exceptions = array();

    /**
     * Template event post ID (for Pro custom rules and series tooling).
     *
     * @var int
     */
    protected $template_post_id = 0;
    
    public function __construct($data) {
        $this->type = $data['type'] ?? 'daily';
        $this->interval = $data['interval'] ?? 1;
        $this->start_date = $data['start_date'] ?? null;
        $this->end_date = $data['end_date'] ?? null;
        $this->timezone = $data['timezone'] ?? wp_timezone_string();
        $this->template_post_id = isset( $data['template_post_id'] ) ? (int) $data['template_post_id'] : 0;
        if ( isset( $data['exceptions'] ) ) {
            $this->exceptions = self::normalize_exceptions( $data['exceptions'] );
        }
    }

    /**
     * Normalize skip/exception dates from pattern data or stored meta (JSON string or array of Y-m-d).
     *
     * @param mixed $raw Array of strings, or JSON array string, or other meta value.
     * @return list<string>
     */
    public static function normalize_exceptions( $raw ) {
        if ( is_array( $raw ) ) {
            $items = $raw;
        } elseif ( is_string( $raw ) && $raw !== '' ) {
            $decoded = json_decode( wp_unslash( $raw ), true );
            $items   = is_array( $decoded ) ? $decoded : array();
        } else {
            return array();
        }

        $out = array();
        foreach ( $items as $item ) {
            if ( ! is_string( $item ) ) {
                continue;
            }
            $item = trim( $item );
            if ( self::is_valid_exception_ymd( $item ) ) {
                $out[] = $item;
            }
        }

        return array_values( array_unique( $out, SORT_STRING ) );
    }

    /**
     * @param string $s Candidate Y-m-d.
     */
    private static function is_valid_exception_ymd( $s ) {
        if ( ! is_string( $s ) || ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $s ) ) {
            return false;
        }
        $parts = array_map( 'intval', explode( '-', $s, 3 ) );
        return checkdate( $parts[1], $parts[2], $parts[0] );
    }
    
    public function get_type() {
        return $this->type;
    }
    
    public function get_interval() {
        return $this->interval;
    }
    
    public function get_start_date() {
        return $this->start_date;
    }
    
    public function get_end_date() {
        return $this->end_date;
    }
    
    public function get_timezone() {
        return $this->timezone;
    }

    /**
     * @return list<string> Local Y-m-d strings excluded from occurrence generation.
     */
    public function get_exceptions() {
        return $this->exceptions;
    }

    /**
     * @return int Template event post ID when set on the pattern (e.g. custom recurrence).
     */
    public function get_template_post_id() {
        return $this->template_post_id;
    }
    
    public function validate() {
        if (empty($this->start_date) || empty($this->end_date)) {
            throw new \Exception('Start date and end date are required');
        }
        
        if (!in_array($this->type, array('daily', 'weekly', 'monthly', 'weekday', 'custom'), true)) {
            throw new \Exception('Invalid recurrence type');
        }
        
        if ($this->interval < 1) {
            throw new \Exception('Interval must be at least 1');
        }
        
        return true;
    }
    
    // Add other getters and validation methods
} 