<?php

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

/**
 * Frontend Handler
 */
class DLift_Frontend
{
  private $active_rule_id = null;

  /**
   * Constructor
   */
  public function __construct()
  {
    add_shortcode('dlift_discount_message', array($this, 'dlift_message_shortcode'));
    add_action('wp_enqueue_scripts', array($this, 'dlift_enqueue_frontend_scripts'));
    add_action('wp_ajax_dlift_get_messages', array($this, 'dlift_get_messages'));
    add_action('wp_ajax_nopriv_dlift_get_messages', array($this, 'dlift_get_messages'));

    // Core discount calculation hooks
    add_action('woocommerce_cart_calculate_fees', array($this, 'dlift_apply_bulk_discount'));

    // Store active rule ID in session when shortcode is rendered
    add_action('template_redirect', array($this, 'dlift_store_active_rule_id'));
  }

  /**
   * Store active rule ID in session
   */
  public function dlift_store_active_rule_id()
  {
    global $post;
    if ($post && has_shortcode($post->post_content, 'dlift_discount_message')) {
      preg_match('/\[dlift_discount_message id="(\d+)"\]/', $post->post_content, $matches);
      if (!empty($matches[1])) {
        WC()->session->set('active_dlift_discount_rule_id', intval($matches[1]));
      }
    }
  }

  /**
   * Get active rule ID from session
   */
  private function dlift_get_active_rule_id()
  {
    if ($this->active_rule_id === null) {
      $this->active_rule_id = WC()->session ? WC()->session->get('active_dlift_discount_rule_id') : 0;
    }
    return $this->active_rule_id;
  }

  /**
   * Handle cart loaded from session
   */
  public function dlift_on_cart_loaded($cart)
  {
    if ($cart) {
      $this->dlift_apply_bulk_discount($cart);
    }
  }


  /**
   * Shortcode handler for discount messages
   */
  public function dlift_message_shortcode($atts)
  {
    $atts = shortcode_atts(array(
      'id' => null,
    ), $atts);

    if (empty($atts['id'])) {
      return '';
    }

    $rule = get_post($atts['id']);
    if (!$rule || $rule->post_type !== 'dlift_discount_rule' || $rule->post_status !== 'publish') {
      return '';
    }

    if (function_exists('WC') && WC()->cart && WC()->cart->is_empty()) {
      return '';
    }

    $cart_total = 0;
    if (function_exists('WC') && WC()->cart) {
      $cart_total = WC()->cart->get_subtotal();
    }

    $condition_value = floatval(get_post_meta($rule->ID, 'dlift_condition_value', true));
    $discount_value = floatval(get_post_meta($rule->ID, 'dlift_discount_value', true));
    $discount_type = sanitize_text_field(get_post_meta($rule->ID, 'dlift_discount_type', true));

    $formatted_discount = $discount_type === 'percentage'
      ? $discount_value . '%'
      : wc_price($discount_value);

    if ($cart_total >= $condition_value) {
      $message = sanitize_text_field(get_post_meta($rule->ID, 'dlift_success_message', true));
      $styles = get_post_meta($rule->ID, 'dlift_success_styles', true);
      $message = str_replace(
        array('{discount}', '{minimum_amount}'),
        array($formatted_discount, wc_price($condition_value)),
        $message
      );
    } else {
      $message = sanitize_text_field(get_post_meta($rule->ID, 'dlift_progress_message', true));
      $styles = get_post_meta($rule->ID, 'dlift_progress_styles', true);
      $remaining_amount = $condition_value - $cart_total;
      $message = str_replace(
        array('{remaining_amount}', '{discount}', '{minimum_amount}'),
        array(wc_price($remaining_amount), $formatted_discount, wc_price($condition_value)),
        $message
      );
    }

    $style = $this->dlift_generate_message_style($styles);

    return sprintf(
      '<div class="dlift-message" data-rule-id="%s" data-shortcode="%s" style="%s">%s</div>',
      esc_attr($rule->ID),
      esc_attr(sprintf('[dlift_discount_message id="%d"]', $rule->ID)),
      esc_attr($style),
      wp_kses_post($message)
    );
  }

  /**
   * Generate message style
   */
  private function dlift_generate_message_style($styles)
  {
    if (!is_array($styles)) {
      $styles = array();
    }

    $transform = array();
    if (!empty($styles['scaleX']) || !empty($styles['scaleY'])) {
      $transform[] = sprintf(
        'scale(%s, %s)',
        !empty($styles['scaleX']) ? floatval($styles['scaleX']) : 1,
        !empty($styles['scaleY']) ? floatval($styles['scaleY']) : 1
      );
    }
    if (!empty($styles['rotate'])) {
      $transform[] = sprintf('rotate(%sdeg)', floatval($styles['rotate']));
    }
    if (!empty($styles['translateX']) || !empty($styles['translateY'])) {
      $transform[] = sprintf(
        'translate(%spx, %spx)',
        !empty($styles['translateX']) ? floatval($styles['translateX']) : 0,
        !empty($styles['translateY']) ? floatval($styles['translateY']) : 0
      );
    }
    if (!empty($styles['skewX']) || !empty($styles['skewY'])) {
      $transform[] = sprintf(
        'skew(%sdeg, %sdeg)',
        !empty($styles['skewX']) ? floatval($styles['skewX']) : 0,
        !empty($styles['skewY']) ? floatval($styles['skewY']) : 0
      );
    }

    $transform_string = !empty($transform) ? implode(' ', $transform) : 'none';
    $transform_origin = !empty($styles['transformOrigin']) ? $styles['transformOrigin'] : 'center';

    // Handle box shadow
    $box_shadow = 'none';
    if (!empty($styles['boxShadow'])) {
      $shadow = $styles['boxShadow'];
      $box_shadow = sprintf(
        '%spx %spx %spx %spx rgba(%s, %s)',
        !empty($shadow['offsetX']) ? floatval($shadow['offsetX']) : 0,
        !empty($shadow['offsetY']) ? floatval($shadow['offsetY']) : 0,
        !empty($shadow['blur']) ? floatval($shadow['blur']) : 0,
        !empty($shadow['spread']) ? floatval($shadow['spread']) : 0,
        !empty($shadow['color']) ? $this->dlift_hex_to_rgb($shadow['color']) : '0, 0, 0',
        !empty($shadow['opacity']) ? floatval($shadow['opacity']) : 0.1
      );
    }

    // Build style string
    $style_parts = array();

    // Basic styles
    if (!empty($styles['backgroundColor'])) {
      $style_parts[] = sprintf('background-color: %s', $styles['backgroundColor']);
    }
    if (!empty($styles['textColor'])) {
      $style_parts[] = sprintf('color: %s', $styles['textColor']);
    }
    if (!empty($styles['borderColor'])) {
      $style_parts[] = sprintf('border-color: %s', $styles['borderColor']);
    }
    if (!empty($styles['borderWidth'])) {
      $style_parts[] = sprintf('border-width: %spx', floatval($styles['borderWidth']));
      $style_parts[] = 'border-style: solid';
    }
    if (!empty($styles['borderRadius'])) {
      $style_parts[] = sprintf('border-radius: %spx', floatval($styles['borderRadius']));
    }
    if (!empty($styles['fontSize'])) {
      $style_parts[] = sprintf('font-size: %spx', floatval($styles['fontSize']));
    }
    if (!empty($styles['padding'])) {
      $style_parts[] = sprintf('padding: %spx', floatval($styles['padding']));
    }
    if (!empty($styles['margin'])) {
      $style_parts[] = sprintf('margin: %spx', floatval($styles['margin']));
    }
    if (!empty($styles['width'])) {
      $style_parts[] = sprintf('width: %s', $styles['width']);
    }
    if (!empty($styles['maxWidth'])) {
      $style_parts[] = sprintf('max-width: %s', $styles['maxWidth']);
    }
    if (!empty($styles['minWidth'])) {
      $style_parts[] = sprintf('min-width: %s', $styles['minWidth']);
    }
    if (!empty($styles['textAlign'])) {
      $style_parts[] = sprintf('text-align: %s', $styles['textAlign']);
    }

    // Transform styles
    if ($transform_string !== 'none') {
      $style_parts[] = sprintf('transform: %s', $transform_string);
      $style_parts[] = sprintf('transform-origin: %s', $transform_origin);
    }

    // Box shadow
    if ($box_shadow !== 'none') {
      $style_parts[] = sprintf('box-shadow: %s', $box_shadow);
    }

    return implode('; ', $style_parts);
  }

  /**
   * Convert hex color to RGB
   */
  private function dlift_hex_to_rgb($hex)
  {
    $hex = str_replace('#', '', $hex);

    if (strlen($hex) == 3) {
      $r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1));
      $g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1));
      $b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1));
    } else {
      $r = hexdec(substr($hex, 0, 2));
      $g = hexdec(substr($hex, 2, 2));
      $b = hexdec(substr($hex, 4, 2));
    }

    return "$r, $g, $b";
  }

  /**
   * AJAX handler for getting messages
   */
  public function dlift_get_messages()
  {
    check_ajax_referer('dlift-frontend', 'nonce');

    $rule_id = isset($_POST['data-rule-id']) ? intval($_POST['data-rule-id']) : 0;
    if (!$rule_id) {
      wp_send_json_error('No rule ID provided');
      return;
    }

    $rule = get_post($rule_id);
    if (!$rule || $rule->post_type !== 'dlift_discount_rule' || $rule->post_status !== 'publish') {
      wp_send_json_error('Invalid rule');
      return;
    }

    $cart_total = WC()->cart ? WC()->cart->get_subtotal() : 0;
    $condition_value = floatval(get_post_meta($rule->ID, 'dlift_condition_value', true));
    $discount_type = sanitize_text_field(get_post_meta($rule->ID, 'dlift_discount_type', true));
    $discount_value = floatval(get_post_meta($rule->ID, 'dlift_discount_value', true));

    $formatted_discount = $discount_type === 'percentage'
      ? $discount_value . '%'
      : wc_price($discount_value);

    if ($cart_total >= $condition_value) {
      $message = sanitize_text_field(get_post_meta($rule->ID, 'dlift_success_message', true));
      $styles = get_post_meta($rule->ID, 'dlift_success_styles', true);
      $message = str_replace(
        array('{discount}', '{minimum_amount}'),
        array($formatted_discount, wc_price($condition_value)),
        $message
      );
    } else {
      $message = sanitize_text_field(get_post_meta($rule->ID, 'dlift_progress_message', true));
      $styles = get_post_meta($rule->ID, 'dlift_progress_styles', true);
      $remaining_amount = $condition_value - $cart_total;
      $message = str_replace(
        array('{remaining_amount}', '{discount}', '{minimum_amount}'),
        array(wc_price($remaining_amount), $formatted_discount, wc_price($condition_value)),
        $message
      );
    }

    $style = $this->dlift_generate_message_style($styles);

    wp_send_json_success(array(
      'style' => esc_attr($style),
      'message' => wp_kses_post($message),
      'is_empty' => empty($message),
      'debug' => array(
        'cart_total' => floatval($cart_total),
        'condition_value' => floatval($condition_value),
        'meets_condition' => (bool)($cart_total >= $condition_value)
      )
    ));
  }

  /**
   * Enqueue frontend scripts
   */
  public function dlift_enqueue_frontend_scripts()
  {
    if (!function_exists('WC')) {
      return;
    }

    wp_enqueue_script(
      'dlift-frontend',
      DLift_PLUGIN_URL . 'src/frontend.js',
      array('jquery'),
      DLift_VERSION,
      true
    );

    wp_localize_script('dlift-frontend', 'dliftSettings', array(
      'ajaxUrl' => admin_url('admin-ajax.php'),
      'nonce' => wp_create_nonce('dlift-frontend')
    ));
  }


  /**
   * Apply bulk discount to cart
   */
  public function dlift_apply_bulk_discount($cart)
  {
    if (!$cart || (is_admin() && !defined('DOING_AJAX'))) {
      return;
    }

    // Prevent infinite loops
    static $is_calculating = false;
    if ($is_calculating) {
      return;
    }
    $is_calculating = true;

    try {
      $cart_total = $cart->get_subtotal();
      $active_rule_id = $this->dlift_get_active_rule_id();

      if (!$active_rule_id) {
        return;
      }

      // Get only the specific rule
      $rule = get_post($active_rule_id);
      if (!$rule || $rule->post_type !== 'dlift_discount_rule' || $rule->post_status !== 'publish') {
        return;
      }

      // Remove existing discounts first
      $fees = $cart->get_fees();
      foreach ($fees as $fee_key => $fee) {
        if (strpos($fee->name, 'Bulk Discount') !== false) {
          unset($cart->fees[$fee_key]);
        }
      }

      $condition_value = floatval(get_post_meta($rule->ID, 'dlift_condition_value', true));
      $discount_type = get_post_meta($rule->ID, 'dlift_discount_type', true);
      $discount_value = floatval(get_post_meta($rule->ID, 'dlift_discount_value', true));

      // Check if cart meets the condition
      if ($cart_total >= $condition_value) {
        $discount_amount = 0;

        if ($discount_type === 'percentage') {
          $discount_amount = ($cart_total * $discount_value) / 100;
          /* translators: %s: Discount percentage value (e.g. "10%") */
          $discount_label = sprintf(
            __('Bulk Discount (%s off)', 'smart-discount'),
            $discount_value . '%'
          );
        } else {
          $discount_amount = $discount_value;
          $discount_label = __('Bulk Discount', 'smart-discount');
        }

        // Apply discount as a negative fee
        $cart->add_fee($discount_label, -$discount_amount, true);
      }
    } finally {
      $is_calculating = false;
    }
  }

  /**
   * Add discount to order
   */
  public function dlift_add_discount_to_order($order)
  {
    if (!$order || (is_admin() && !defined('DOING_AJAX'))) {
      return;
    }

    // Prevent infinite loops
    static $is_calculating = false;
    if ($is_calculating) {
      return;
    }
    $is_calculating = true;

    try {
      $order_subtotal = $order->get_total();
      $active_rule_id = $this->dlift_get_active_rule_id();

      if (!$active_rule_id) {
        return;
      }

      // Get only the specific rule
      $rule = get_post($active_rule_id);
      if (!$rule || $rule->post_type !== 'dlift_discount_rule' || $rule->post_status !== 'publish') {
        return;
      }

      $condition_value = floatval(get_post_meta($rule->ID, 'dlift_condition_value', true));
      $discount_type = get_post_meta($rule->ID, 'dlift_discount_type', true);
      $discount_value = floatval(get_post_meta($rule->ID, 'dlift_discount_value', true));

      if ($order_subtotal >= $condition_value) {
        $discount_amount = $discount_type === 'percentage'
          ? ($order_subtotal * $discount_value / 100)
          : $discount_value;

        $discount_label = $discount_type === 'percentage'
          /* translators: %s: Discount percentage value (e.g. "10%") */
          ? sprintf(__('Bulk Discount (%s off)', 'smart-discount'), $discount_value . '%')
          : __('Bulk Discount', 'smart-discount');

        $fee = new WC_Order_Item_Fee();
        $fee->set_name($discount_label);
        $fee->set_amount(-$discount_amount);
        $fee->set_total(-$discount_amount);

        $order->add_item($fee);
      }
    } finally {
      $is_calculating = false;
    }
  }
}
