<?php
namespace Indeed\Uap;

class UapGDPR
{
  private $pluginName = UAP_NAME;
  private $uid = 0;
  private $affiliateId = 0;

  public function __construct()
  {
      add_action('admin_init', [$this, 'privacyPolicy']);
      add_filter('wp_privacy_personal_data_exporters', [$this, 'registerExport']);
      add_filter('wp_privacy_personal_data_erasers', [$this, 'registerErase']);
  }

  public function privacyPolicy()
  {
      if (!function_exists('wp_add_privacy_policy_content')){
          return;
      }
      wp_add_privacy_policy_content($this->pluginName, '');
  }

  public function registerExport($exporters = [])
  {
      $exporters['ua-exporter'] = [
          'exporter_friendly_name' => $this->pluginName,
          'callback'               => [$this, 'doExport'],
      ];
      return $exporters;
  }

  public function registerErase($erasers = [])
  {
      $erasers['ua-eraser'] = [
          'eraser_friendly_name' => $this->pluginName,
          'callback'             => [$this, 'doErase'],
      ];
      return $erasers;
  }

  public function doExport($emailAddress = '', $page = 1)
  {
      global $indeed_db;

      $user = get_user_by('email', $emailAddress);
      $this->uid = $user->ID ?? 0;
      $this->affiliateId = $indeed_db->get_affiliate_id_by_wpuid($this->uid);

      if (!$this->uid || !$this->affiliateId) {
          return ['data' => [], 'done' => true];
      }

      $exportData = [];

      foreach ([
          $this->getUserMetas(),
          $this->getAffiliateData(),
          $this->getOffers(),
          $this->getCampaigns(),
          $this->getPayments(),
          $this->getRanksHistory(),
          $this->getCoupons(),
          $this->getReports(),
          $this->getRefLinks(),
      ] as $section) {
          if (!empty($section)) {
              $exportData[] = $section;
          }
      }

      return [
          'data' => $exportData,
          'done' => true
      ];
  }

  public function doErase($emailAddress = '', $page = 1)
  {
      global $indeed_db, $wpdb;

      $user = get_user_by('email', $emailAddress);
      $this->uid = $user->ID ?? 0;
      $this->affiliateId = $indeed_db->get_affiliate_id_by_wpuid($this->uid);

      if (!$this->uid || !$this->affiliateId) {
          return ['items_removed' => false, 'done' => true];
      }

      $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE user_id={$this->uid} AND meta_key LIKE '%uap_%'");

      $tables = [
          'uap_affiliates' => 'uid',
          'uap_offers_affiliates_reference' => 'affiliate_id',
          'uap_campaigns' => 'affiliate_id',
          'uap_payments' => 'affiliate_id',
          'uap_ranks_history' => 'affiliate_id',
          'uap_coupons_code_affiliates' => 'affiliate_id',
          'uap_reports' => 'affiliate_id',
          'uap_ref_links' => 'affiliate_id',
      ];

      foreach ($tables as $table => $column) {
          $value = ($column === 'uid') ? $this->uid : $this->affiliateId;
          $wpdb->query($wpdb->prepare(
              "DELETE FROM {$wpdb->prefix}{$table} WHERE {$column}=%d",
              $value
          ));
      }

      return [
          'items_removed' => true,
          'items_retained' => false,
          'messages' => [],
          'done' => true,
      ];
  }

  /* ================= HELPERS ================= */

  private function buildGroup($id, $label, $data)
  {
      if (empty($data)) return false;

      return [
          'group_id'    => $id,
          'group_label' => $label,
          'item_id'     => $id . '_' . $this->uid,
          'data'        => $data,
      ];
  }

  /* ================= DATA METHODS ================= */

  private function getUserMetas()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT meta_key, meta_value FROM {$wpdb->usermeta}
           WHERE user_id=%d AND meta_key LIKE '%uap_%'",
          $this->uid
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => $row->meta_key,
              'value' => $row->meta_value,
          ];
      }

      return $this->buildGroup('uap_user_metas', $this->pluginName . ' - Affiliate User Metas', $data ?? []);
  }

  private function getAffiliateData()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT rank_id, start_data, status FROM {$wpdb->prefix}uap_affiliates WHERE uid=%d",
          $this->uid
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Affiliate #' . $this->affiliateId,
              'value' => "Rank: {$row->rank_id}, Start: {$row->start_data}, Status: {$row->status}",
          ];
      }

      return $this->buildGroup('uap_affiliate', $this->pluginName . ' - Affiliate Account', $data ?? []);
  }

  private function getOffers()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT source, products FROM {$wpdb->prefix}uap_offers_affiliates_reference WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Source: ' . $row->source,
              'value' => 'Products: ' . $row->products,
          ];
      }
      $table = 'uap_offers';
      return $this->buildGroup( $table, $this->pluginName . ' - Affiliate Offers', $data ?? []);
  }

  private function getCampaigns()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT name, referrals, visit_count, unique_visits_count FROM {$wpdb->prefix}uap_campaigns WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Campaign: ' . $row->name,
              'value' => "Referrals: {$row->referrals}, Visits: {$row->visit_count}, Unique: {$row->unique_visits_count}",
          ];
      }

      return $this->buildGroup('uap_campaigns', $this->pluginName . ' - Affiliate Campaigns', $data ?? []);
  }

  private function getPayments()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT transaction_id, amount, currency, status FROM {$wpdb->prefix}uap_payments WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Transaction #' . $row->transaction_id,
              'value' => "Amount: {$row->amount} {$row->currency}, Status: {$row->status}",
          ];
      }

      return $this->buildGroup('uap_payments', $this->pluginName . ' - Affiliate Payments', $data ?? []);
  }

  private function getRanksHistory()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT prev_rank_id, rank_id, add_date FROM {$wpdb->prefix}uap_ranks_history WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => "Rank change",
              'value' => "From {$row->prev_rank_id} to {$row->rank_id} at {$row->add_date}",
          ];
      }

      return $this->buildGroup('uap_ranks_history', $this->pluginName . ' - Rank History', $data ?? []);
  }

  private function getCoupons()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT code, status FROM {$wpdb->prefix}uap_coupons_code_affiliates WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Coupon: ' . $row->code,
              'value' => 'Status: ' . $row->status,
          ];
      }

      return $this->buildGroup('uap_coupons', $this->pluginName . ' - Affiliate Coupons', $data ?? []);
  }

  private function getReports()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT email, period, last_sent FROM {$wpdb->prefix}uap_reports WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'Report: ' . $row->email,
              'value' => "Period: {$row->period}, Last sent: {$row->last_sent}",
          ];
      }

      return $this->buildGroup('uap_reports', $this->pluginName . ' - Affiliate Reports', $data ?? []);
  }

  private function getRefLinks()
  {
      global $wpdb;

      $results = $wpdb->get_results($wpdb->prepare(
          "SELECT url, status FROM {$wpdb->prefix}uap_ref_links WHERE affiliate_id=%d",
          $this->affiliateId
      ));

      foreach ($results as $row) {
          $data[] = [
              'name'  => 'URL',
              'value' => "{$row->url} (Status: {$row->status})",
          ];
      }

      return $this->buildGroup('uap_ref_links', $this->pluginName . ' - Referral Links', $data ?? []);
  }

}
