<?php

namespace Pixeldev\SquareWooSync\Woo;

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

class ValidateWooProduct
{
  public function init()
  {
    add_action('wp_ajax_check_export_validation', [$this, 'check_export_validation']);
    add_action('wp_ajax_nopriv_check_export_validation', [$this, 'check_export_validation']);

    add_action('wp_ajax_check_sync_validation', [$this, 'check_sync_validation']);
    add_action('wp_ajax_nopriv_check_sync_validation', [$this, 'check_sync_validation']);
  }

  public function check_export_validation()
  {
    check_ajax_referer('sws_ajax_nonce', 'nonce');

    $product_id = isset($_POST['product_id']) ? (int) $_POST['product_id'] : 0;
    $export_fields = isset($_POST['export_fields']) ? (array) $_POST['export_fields'] : [];

    if (!$product_id) {
      wp_send_json_error([
        'message' => 'No product ID provided.',
        'reasons' => ['No product ID provided.'],
      ]);
    }

    $non_image_fields = array_diff($export_fields, ['images']);
    $result = $this->validateProduct($product_id, $non_image_fields);
    $imageWarnings = [];

    if (in_array('images', $export_fields, true)) {
      $imageOnlyResult = $this->validateProduct($product_id, ['images']);
      $imageWarnings = array_diff($imageOnlyResult['reasons'], $result['reasons']);
    }

    if (!$result['success']) {
      wp_send_json_error([
        'message' => 'Cannot export product.',
        'reasons' => array_merge($result['reasons'], $imageWarnings),
      ]);
    }

    wp_send_json_success([
      'message' => 'Product is valid for export.',
      'reasons' => $imageWarnings,
    ]);
  }

  public function check_sync_validation()
  {
    check_ajax_referer('sws_ajax_nonce', 'nonce');

    $product_id = isset($_POST['product_id']) ? (int) $_POST['product_id'] : 0;
    $sync_fields = isset($_POST['sync_fields']) ? (array) $_POST['sync_fields'] : [];

    if (!$product_id) {
      wp_send_json_error([
        'message' => 'No product ID provided.',
        'reasons' => ['No product ID provided.'],
      ]);
    }

    $warnings = [];
    $product = wc_get_product($product_id);

    if ($product && $product->is_type('variable')) {
      foreach ($product->get_children() as $vid) {
        $result = $this->validateVariation($vid, in_array('images', $sync_fields, true));
        if (!$result['success']) {
          $variation = wc_get_product($vid);
          $label = $variation ? $variation->get_formatted_name() : "Variation ID $vid";
          foreach ($result['reasons'] as $reason) {
            $warnings[] = "$label skipped: $reason";
          }
        }
      }
    }

    wp_send_json_success([
      'message' => 'Sync will proceed, but some variations may be skipped.',
      'reasons' => $warnings,
    ]);
  }

  public function validateProduct($product_id, $export_fields = [])
  {
    $product = wc_get_product($product_id);
    if (!$product) {
      return [
        'success' => false,
        'reasons' => ['Invalid product or product does not exist.'],
      ];
    }

    $reasons = [];
    $is_variable = $product->is_type('variable');

    if (empty($product->get_name())) {
      $reasons[] = 'Missing product title.';
    }

    if ($is_variable) {
      $variation_ids = $product->get_children();
      if (count($variation_ids) < 2) {
        $reasons[] = 'A variable product must have at least 2 variations.';
      }

      foreach ($variation_ids as $vid) {
        $variation = wc_get_product($vid);
        if (!$variation) continue;

        $skip = apply_filters(
          'squarewoosync_skip_variation_sync',
          get_post_meta($vid, 'square_skip_sync', true) === 'yes',
          $vid,
          $variation
        );
        if ($skip) continue;

        if (floatval($variation->get_price()) <= 0) {
          $reasons[] = 'Variation "' . $variation->get_name() . '" has no valid price.';
        }
        if ($variation->managing_stock() && is_null($variation->get_stock_quantity())) {
          $reasons[] = 'Variation "' . $variation->get_name() . '" is tracking stock but has no quantity set.';
        }
        foreach ($variation->get_variation_attributes() as $attr_value) {
          if (empty($attr_value) || strtolower($attr_value) === 'any') {
            $reasons[] = 'Variation "' . $variation->get_name() . '" has an attribute set to "any" or empty.';
          }
        }
      }
    } else {
      if (floatval($product->get_price()) <= 0) {
        $reasons[] = 'Product price is missing or zero.';
      }
      if ($product->managing_stock() && is_null($product->get_stock_quantity())) {
        $reasons[] = 'Product is tracking stock but has no quantity set.';
      }
    }

    if (in_array('images', $export_fields, true)) {
      $image_ids = array_filter([
        $product->get_image_id(),
        ...$product->get_gallery_image_ids(),
        ...array_map(function ($vid) {
          $v = wc_get_product($vid);
          return $v ? $v->get_image_id() : null;
        }, $product->is_type('variable') ? $product->get_children() : [])
      ]);

      $image_ids = array_unique($image_ids);
      if (count($image_ids) > 250) {
        $reasons[] = 'Too many images (max 250 allowed).';
      }

      foreach ($image_ids as $id) {
        $file = get_attached_file($id);
        if (!$file || !file_exists($file)) {
          $reasons[] = "Image attachment ID {$id} is missing or file does not exist.";
          continue;
        }
        if (filesize($file) > 250 * 1024 * 1024) {
          $reasons[] = "Image attachment ID {$id} exceeds 250MB and will be skipped.";
        }
        $mime = wp_check_filetype($file)['type'];
        if (!in_array($mime, ['image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'], true)) {
          $reasons[] = "Image attachment ID {$id} has unsupported format ($mime) and will be skipped.";
        }
      }
    }

    if (in_array('categories', $export_fields, true)) {
      $cats = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']);
      if (empty($cats)) {
        $reasons[] = 'Product has no categories.';
      }
    }

    return [
      'success' => empty($reasons),
      'reasons' => $reasons,
    ];
  }

  public function validateVariation($variation_id, $check_images = true)
  {
    $variation = wc_get_product($variation_id);
    if (!$variation || !$variation->is_type('variation')) {
      return [
        'success' => false,
        'variation_id' => $variation_id,
        'product_id' => 0,
        'square_product_id' => null,
        'reasons' => ['Invalid variation.'],
      ];
    }

    $reasons = [];
    $parent_id = $variation->get_parent_id();
    $square_product_id = get_post_meta($variation_id, 'square_product_id', true) ?: null;

    $skip = apply_filters(
      'squarewoosync_skip_variation_sync',
      get_post_meta($variation_id, 'square_skip_sync', true) === 'yes',
      $variation_id,
      $variation
    );
    if ($skip) {
      return [
        'success' => false,
        'variation_id' => $variation_id,
        'product_id' => $parent_id,
        'square_product_id' => $square_product_id,
        'reasons' => ['Marked to skip.'],
      ];
    }

    if (floatval($variation->get_price()) <= 0) {
      $reasons[] = 'Missing or invalid price.';
    }
    if ($variation->managing_stock() && is_null($variation->get_stock_quantity())) {
      $reasons[] = 'Stock tracking enabled, but no quantity set.';
    }
    foreach ($variation->get_variation_attributes() as $value) {
      if (empty($value) || strtolower($value) === 'any') {
        $reasons[] = 'Empty or "any" attribute found.';
      }
    }

    if ($check_images) {
      $image_id = $variation->get_image_id();
      if ($image_id) {
        $file = get_attached_file($image_id);
        if (!$file || !file_exists($file)) {
          $reasons[] = "Variation image file not found (ID $image_id).";
        } else {
          if (filesize($file) > 250 * 1024 * 1024) {
            $reasons[] = "Variation image exceeds 250MB (ID $image_id).";
          }
          $mime = wp_check_filetype($file)['type'];
          if (!in_array($mime, ['image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'], true)) {
            $reasons[] = "Invalid variation image format (ID $image_id, $mime).";
          }
        }
      }
    }

    return [
      'success' => empty($reasons),
      'variation_id' => $variation_id,
      'product_id' => $parent_id,
      'square_product_id' => $square_product_id,
      'reasons' => $reasons,
    ];
  }
}
