<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\SendingServer;
use App\Http\Helper\Helper;
use DB;

class CallbackController extends Controller
{
    public function __construct(Request $request)
    {
      /*$callback = $request->all();
      $request_data = print_r($callback, true);
      $str = "Request Data ".date("Y-m-d H:i:s")." \n $request_data";
      $file_path = storage_path().DIRECTORY_SEPARATOR.'callback_request.txt';
      $fp = fopen($file_path, 'a');
      fwrite($fp, $str);
      fclose($fp);*/

      // Get Amazon Callback
      $callback = json_decode(file_get_contents('php://input'), true);
      if(!empty($callback) && (!empty($callback['SubscribeURL']) || !empty($callback['Message']))) {
        $this->amazon($callback);
      }
    }

    // MailGun Callback
    public function mailgun(Request $request)
    {
        $callback = $request->all();
        $callback['message_id'] = $callback['event-data']['message']['headers']['message-id'] ?? null;
        if($callback['message_id']) {
          list($table, $stat_id, $to_email, $sending_server, $section, $app_id,$schedule_id) = Helper::statMessageDetail($callback['message_id']);
          $sending_attributes = json_decode(SendingServer::whereName($sending_server)->whereAppId($app_id)->value('sending_attributes'));
          // If process is enabled within sending server settings
          if(!empty($sending_attributes->process_reports) && $sending_attributes->process_reports == 'yes') {
            if($stat_id) {
              $callback['event'] = $callback['event-data']['event'] ?? null;
              $short_detail = $full_detail = $callback['event-data']['delivery-status']['description'] ?? $callback['event-data']['delivery-status']['message'] ?? null;

              $status = null;
              if($callback['event'] == 'failed' || $callback['event'] == 'bounce' || $callback['event'] == 'suppress-bounce') {
                $code = $callback['event-data']['delivery-status']['code'] ?? '511';
                $type = Helper::bouceCodes($code)['type'] ?? 'Hard';
                // Save bounce data
                Helper::saveBounce($schedule_id, $to_email, $stat_id, $section, $code, $type, $short_detail, $full_detail, $app_id);
                $status = 'Bounced';
              } elseif($callback['event'] == 'complained') {
                // Save spam data
                Helper::saveSpam($to_email, $stat_id, $section, $full_detail, $app_id);
                $status = 'Spammed';
              }

              if($status) {
                // Update email status
                DB::table($table)->whereId($stat_id)->update(['status' => $status]);
              }
            }
          }
        }
        return response()->json(['success' => true],200);
    }

    // SendGrid Callback
    public function sendgrid(Request $request)
    {
        $callbacks = $request->all();
        foreach ($callbacks as $callback) {
          // no need to chek processed request to reduece checks, because each email has processed callback data
          if($callback['event'] == 'processed') continue;

          $callback['message_id'] = $callback['mc_message_id'] ?? null;
          if($callback['message_id']) {
            list($table, $stat_id, $to_email, $sending_server, $section, $app_id, $schedule_id) = Helper::statMessageDetail($callback['message_id']);
            $sending_attributes = json_decode(SendingServer::whereName($sending_server)->whereAppId($app_id)->value('sending_attributes'));
            // If process is enabled within sending server settings
            if(!empty($sending_attributes->process_reports) && $sending_attributes->process_reports == 'yes') {
              if($stat_id) {
                $short_detail = $full_detail = $callback['reason'] ?? null;

                $status = null;
                if($callback['event'] == 'bounce' || $callback['event'] == 'deferred' || 
                  $callback['event'] == 'dropped' || $callback['event'] == 'blocked') {
                  $code = $callback['status'] ?? '5.1.1';
                  $type = Helper::bouceCodes($code)['type'] ?? 'Hard';
                  // Save bounce data
                  Helper::saveBounce($schedule_id, $to_email, $stat_id, $section, $code, $type, $short_detail, $full_detail, $app_id);
                  $status = 'Bounced';
                } elseif($callback['event'] == 'complained') {
                  // Save spam data
                  Helper::saveSpam($to_email, $stat_id, $section, $full_detail, $app_id);
                  $status = 'Spammed';
                }

                if($status) {
                  // Update email status
                  DB::table($table)->whereId($stat_id)->update(['status' => $status]);
                }
              }
            }
          }
        }
        return response()->json(['success' => true],200);
    }

    // Spartpost Callback
    public function sparkpost(Request $request)
    {
      $callbacks = $request->all();
      foreach ($callbacks as $callback) {
          $email = $callback['msys']['message_event']['rcpt_to'] ?? null;
          if($email) {
            list($table, $stat_id, $to_email, $sending_server, $section, $app_id, $schedule_id) = Helper::statMessageDetail('none', $email);
            $sending_attributes = json_decode(SendingServer::whereName($sending_server)->whereAppId($app_id)->value('sending_attributes'));
            // If process is enabled within sending server settings
            if(!empty($sending_attributes->process_reports) && $sending_attributes->process_reports == 'yes') {
              if($stat_id) {
                $short_detail = $full_detail = $callback['msys']['message_event']['reason'] ?? null;

                $status = null;
                if($callback['msys']['message_event']['type'] == 'bounce') {
                  $code = $callback['msys']['message_event']['error_code'] ?? '5.1.1';
                  $type = Helper::bouceCodes($code)['type'] ?? 'Hard';
                  // Save bounce data
                  Helper::saveBounce($schedule_id, $to_email, $stat_id, $section, $code, $type, $short_detail, $full_detail, $app_id);
                  $status = 'Bounced';
                } elseif($callback['event'] == 'complained') {
                  // Save spam data
                  Helper::saveSpam($to_email, $stat_id, $section, $full_detail, $app_id);
                  $status = 'Spammed';
                }

                if($status) {
                  // Update email status
                  DB::table($table)->whereId($stat_id)->update(['status' => $status]);
                }
              }
            }
          }
      }
      return response()->json(['success' => true],200);
    }


    // Amazon Callback
    public function amazon($callback=null)
    {
        // Get Amazon callback response
        if(!empty($callback['SubscribeURL'])) {
          $file_path = storage_path().DIRECTORY_SEPARATOR."amazonsns.txt";
          $fp = fopen($file_path, 'w');
          fwrite($fp, print_r($callback['SubscribeURL'], true));
          fclose($fp);
        } elseif(!empty($callback['Message'])) {
          $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
          $fp = fopen($file_path, 'a');
          fwrite($fp, print_r($callback, true));
          fclose($fp);

          if(!empty($callback)) {
            $message = json_decode($callback['Message'], true);

            // get system generated message id location
            $mail_header_keys = array_column($message['mail']['headers'], 'name');
            $mail_header_message_id_location = array_search('Message-ID', array_keys($mail_header_keys));

            $callback['message_id'] = trim($message['mail']['headers'][$mail_header_message_id_location]['value']) ?? null; //message id
            $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
            $fp = fopen($file_path, 'a');
            fwrite($fp, print_r("Message-ID: {$callback['message_id']}", true));
            fclose($fp);

            if($callback['message_id']) {
              // remove characters from message-id
              $callback['message_id'] = str_replace(['<', '>'], '', $callback['message_id']);
              list($table, $stat_id, $to_email, $sending_server, $section, $app_id, $schedule_id) = Helper::statMessageDetail($callback['message_id']);
              $sending_attributes = json_decode(SendingServer::whereName($sending_server)->whereAppId($app_id)->value('sending_attributes'));
              // If process is enabled within sending server settings
              if(!empty($sending_attributes->process_reports) && $sending_attributes->process_reports == 'yes') {
                if($stat_id) {
                  $callback['event'] = ($message['notificationType']) ?? (($message['eventType']) ?? null);
                  $callback['event'] = trim($callback['event']);
                  $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
                  $fp = fopen($file_path, 'a');
                  fwrite($fp, print_r("Event: {$callback['event']}", true));
                  fclose($fp);

                  $short_detail = $full_detail = !empty($message['bounce']['bouncedRecipients'][0]['diagnosticCode']) ? $message['bounce']['bouncedRecipients'][0]['diagnosticCode']: null;

                  $status = null;
                  if($callback['event'] == 'Bounce' || $callback['event'] == 'Reject' || $callback['event'] == 'Rendering Failure') {

                    $code =  empty($message['bounce']['bouncedRecipients'][0]['status']) ? '5.1.1' : $message['bounce']['bouncedRecipients'][0]['status'];

                    $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
                    $fp = fopen($file_path, 'a');
                    fwrite($fp, print_r("code: {$code}", true));
                    fclose($fp);

                    if(empty($message['bounce']['bouncedRecipients'][0]['diagnosticCode'])){
                      $bounce_code_detail = Helper::bouceCodes($code);
                      $short_detail = $full_detail = $bounce_code_detail['description'];
                    }

                    $type = !empty(Helper::bouceCodes($code)['type']) ? Helper::bouceCodes($code)['type'] : 'Hard';

                    $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
                    $fp = fopen($file_path, 'a');
                    fwrite($fp, print_r("type: {$code}", true));
                    fclose($fp);
                    // Save bounce data
                    $file_path = storage_path().DIRECTORY_SEPARATOR."amazonses.txt";
                    $fp = fopen($file_path, 'a');
                    fwrite($fp, print_r("saveBounce: {$to_email}, {$stat_id}, {$section}, {$code}, {$type}, {$short_detail}, {$full_detail}, {$app_id}", true));
                    fclose($fp);

                    Helper::saveBounce($schedule_id, $to_email, $stat_id, $section, $code, $type, $short_detail, $full_detail, $app_id);
                    $status = 'Bounced';
                  } elseif($callback['event'] == 'Complaint') {
                    // Save spam data
                    Helper::saveSpam($to_email, $stat_id, $section, $full_detail, $app_id);
                    $status = 'Spammed';
                  }

                  if($status) {
                    // Update email status
                    DB::table($table)->whereId($stat_id)->update(['status' => $status]);
                  }
                }
              }
            }
          }
        }
        return response()->json(['success' => true],200);
    }

}