// TrendyolGo (tgoyemek.com) sepet kupon/promosyon düzeltmesi.
// document_start + MAIN world'da çalışır; dış bağımlılığı yoktur.
//
// SORUN: "İlk 5 Siparişe Özel -300" indirimi sepetin /carts ucundan gelmiyor.
// O indirim ödeme katmanındaki şu istekten hesaplanıyor:
//   POST https://payment.tgoapps.com/v3/payment/options
// Sepet sayfası bu isteği yapmadığı için indirim sadece ödeme adımında görünüyor.
//
// ÇÖZÜM: Sepet (GET .../carts) yanıtı geldiğinde arka planda payment/options
// çağrılır; daha avantajlı toplam (İlk5) varsa sepet yanıtına enjekte edilir.

(function () {
  'use strict';

  var DEBUG = true;
  var TAG = '[TGO-PROMO]';

  var CART_PATH_RE = /\/web-checkout-apicheckout-santral\/carts$/;
  var OPTIONS_URL = 'https://payment.tgoapps.com/v3/payment/options';

  // Sayfanın istek başlıklarından yakalanan en son Authorization token'ı.
  var AUTH = null;

  // Sayfanın gerçek payment/options isteği (varsa) — birebir tekrar oynatmak için.
  var CAPTURED_OPTIONS_HEADERS = null;
  var CAPTURED_OPTIONS_BODY = null;
  try {
    var _saved = sessionStorage.getItem('tgo_options_req');
    if (_saved) {
      var _o = JSON.parse(_saved);
      CAPTURED_OPTIONS_HEADERS = _o.headers || null;
      CAPTURED_OPTIONS_BODY = _o.body || null;
    }
  } catch (_) {}

  // payment/options için bilinen-çalışan varsayılan başlık ve gövde.
  var DEFAULT_OPTIONS_HEADERS = {
    'content-type': 'application/json',
    'app-name': 'TrendyolGo',
    'x-applicationid': '1',
    'x-channelid': '4',
    'x-storefrontid': '1',
    'x-features': 'OPTIONAL_REBATE;MEAL_CART_ENABLED;MEAL_CARD_TRENDYOL_PROMOTION;PICKUP_FEE_ENABLED;VAS_QUANTITY_ENABLED;',
    'x-supported-payment-options': 'MULTINET;SODEXO;EDENRED;ON_DELIVERY;SETCARD',
    'accept-language': 'tr-TR',
    'x-session-id': '',
    'x-personalization-id': ''
  };
  var DEFAULT_OPTIONS_BODY = '{"paymentType":"payWithCard","data":{"savedCardId":0,"binCode":""}}';

  function captureOptionsReq(headers, body) {
    try {
      if (headers) CAPTURED_OPTIONS_HEADERS = headers;
      if (typeof body === 'string') CAPTURED_OPTIONS_BODY = body;
      sessionStorage.setItem('tgo_options_req', JSON.stringify({
        headers: CAPTURED_OPTIONS_HEADERS,
        body: CAPTURED_OPTIONS_BODY
      }));
    } catch (_) {}
  }

  function log() {
    if (!DEBUG) return;
    try {
      var args = Array.prototype.slice.call(arguments);
      args.unshift(TAG);
      console.log.apply(console, args);
    } catch (_) {}
  }

  log('interceptor yüklendi @', location.href);

  function uuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = (Math.random() * 16) | 0;
      var v = c === 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });
  }

  function parseUrl(urlStr) {
    try { return new URL(urlStr, window.location.href); } catch (_) { return null; }
  }

  function isCartsGetUrl(urlStr) {
    var u = parseUrl(urlStr);
    if (!u) return false;
    if (u.hostname.toLowerCase() !== 'api.tgoapis.com') return false;
    return CART_PATH_RE.test(u.pathname);
  }

  function captureAuth(value) {
    if (value && /bearer/i.test(value)) AUTH = value;
  }

  // ─── Saklı fetch referansı (kendi isteklerimizde override'a girmemek için) ────
  var _origFetch = window.fetch;

  // ─── payment/options çağrısı (İlk5 indirimini hesaplatır) ────────────────────
  function fetchPaymentOptions(token) {
    var auth = token || AUTH;
    if (!auth) {
      log('Authorization token yok, payment/options atlandı');
      return Promise.resolve(null);
    }

    var src = CAPTURED_OPTIONS_HEADERS || DEFAULT_OPTIONS_HEADERS;
    var headers = {};
    for (var k in src) {
      if (!Object.prototype.hasOwnProperty.call(src, k)) continue;
      if (String(k).toLowerCase() === 'authorization') continue;
      headers[k] = src[k];
    }
    headers['authorization'] = auth;
    if (!headers['content-type'] && !headers['Content-Type']) headers['content-type'] = 'application/json';

    var body = CAPTURED_OPTIONS_BODY || DEFAULT_OPTIONS_BODY;

    return _origFetch.call(window, OPTIONS_URL, {
      method: 'POST',
      headers: headers,
      body: body
    }).then(function (r) {
      if (!r.ok) { log('payment/options HTTP', r.status); return null; }
      return r.json();
    }).catch(function (e) {
      log('payment/options hata:', e && e.message);
      return null;
    });
  }

  // ─── İlk5 indirimini sepet nesnesine enjekte et ──────────────────────────────
  function mergeOptionsIntoCart(cartsObj, opt) {
    if (!opt || !opt.prices || typeof opt.prices.totalPrice !== 'number') return false;
    if (typeof cartsObj.totalPrice !== 'number') return false;
    // Yalnızca daha avantajlı (daha düşük) toplam varsa uygula.
    if (opt.prices.totalPrice >= cartsObj.totalPrice) return false;

    if (Array.isArray(opt.summary) && opt.summary.length) cartsObj.summary = opt.summary;
    cartsObj.totalPrice = opt.prices.totalPrice;
    cartsObj.totalProductPriceDiscounted = opt.prices.totalPrice;
    if (typeof opt.prices.basePrice === 'number') cartsObj.basePrice = opt.prices.basePrice;
    if (typeof opt.prices.totalPromotionPrice === 'number') cartsObj.totalPromotionPrice = opt.prices.totalPromotionPrice;
    if (typeof opt.prices.totalCouponPrice === 'number') cartsObj.totalCouponPrice = opt.prices.totalCouponPrice;
    if (typeof opt.prices.totalSellerPaidDiscount === 'number') cartsObj.totalSellerPaidDiscount = opt.prices.totalSellerPaidDiscount;
    if (typeof opt.prices.deliveryPrice === 'number') cartsObj.deliveryPrice = opt.prices.deliveryPrice;
    return true;
  }

  // Orijinal sepet yanıtını al + İlk5'i enjekte et. Her durumda metin döndürür.
  // -> { status, text, contentType }
  function buildMergedCarts(url, headerObj) {
    var ct = 'application/json; charset=utf-8';
    return _origFetch.call(window, url, {
      method: 'GET',
      headers: headerObj,
      credentials: 'include'
    }).then(function (r) {
      ct = r.headers.get('content-type') || ct;
      return r.text().then(function (cartsText) {
        var status = r.status;
        var cartsObj;
        try { cartsObj = JSON.parse(cartsText); } catch (_) { return { status: status, text: cartsText, contentType: ct }; }

        var token = headerObj['authorization'] || headerObj['Authorization'] || AUTH;
        return fetchPaymentOptions(token).then(function (opt) {
          try {
            if (mergeOptionsIntoCart(cartsObj, opt)) {
              log('Sepete İlk5 enjekte edildi -> totalPrice:', cartsObj.totalPrice);
              return { status: 200, text: JSON.stringify(cartsObj), contentType: ct };
            }
          } catch (e) { log('merge hata:', e && e.message); }
          return { status: status, text: cartsText, contentType: ct };
        });
      });
    }).catch(function (e) {
      log('buildMergedCarts hata:', e && e.message);
      return { status: 0, text: '', contentType: ct };
    });
  }

  function headerMapToObject(map) {
    var obj = {};
    for (var k in map) { if (Object.prototype.hasOwnProperty.call(map, k)) obj[k] = map[k]; }
    return obj;
  }

  // ─── XMLHttpRequest override (carts isteği axios/XHR ile gidiyor) ─────────────
  var _origOpen = XMLHttpRequest.prototype.open;
  var _origSend = XMLHttpRequest.prototype.send;
  var _origSetHeader = XMLHttpRequest.prototype.setRequestHeader;

  XMLHttpRequest.prototype.open = function (method, url) {
    try {
      this._tgoMethod = (method || 'GET').toUpperCase();
      this._tgoUrl = typeof url === 'string' ? url : String(url);
      this._tgoHeaders = {};
      this._tgoIsCartsGet = this._tgoMethod === 'GET' && isCartsGetUrl(this._tgoUrl);
    } catch (_) {}
    return _origOpen.apply(this, arguments);
  };

  XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
    try {
      this._tgoHeaders = this._tgoHeaders || {};
      this._tgoHeaders[String(name).toLowerCase()] = value;
      if (String(name).toLowerCase() === 'authorization') captureAuth(value);
    } catch (_) {}
    return _origSetHeader.apply(this, arguments);
  };

  function deliverFakeResponse(xhr, status, text, contentType) {
    try {
      Object.defineProperty(xhr, 'readyState', { configurable: true, get: function () { return 4; } });
      Object.defineProperty(xhr, 'status', { configurable: true, get: function () { return status; } });
      Object.defineProperty(xhr, 'statusText', { configurable: true, get: function () { return 'OK'; } });
      Object.defineProperty(xhr, 'responseText', { configurable: true, get: function () { return text; } });
      Object.defineProperty(xhr, 'response', { configurable: true, get: function () { return text; } });
      var ct = contentType || 'application/json; charset=utf-8';
      xhr.getResponseHeader = function (n) { return String(n).toLowerCase() === 'content-type' ? ct : null; };
      xhr.getAllResponseHeaders = function () { return 'content-type: ' + ct + '\r\n'; };
    } catch (_) {}
    setTimeout(function () {
      try { if (typeof xhr.onreadystatechange === 'function') xhr.onreadystatechange(); } catch (_) {}
      try { if (typeof xhr.onload === 'function') xhr.onload(); } catch (_) {}
      try { if (typeof xhr.onloadend === 'function') xhr.onloadend(); } catch (_) {}
      try { xhr.dispatchEvent(new Event('readystatechange')); } catch (_) {}
      try { xhr.dispatchEvent(new Event('load')); } catch (_) {}
      try { xhr.dispatchEvent(new Event('loadend')); } catch (_) {}
    }, 0);
  }

  XMLHttpRequest.prototype.send = function (body) {
    try {
      if (this._tgoMethod === 'POST' && this._tgoUrl && this._tgoUrl.indexOf('/v3/payment/options') !== -1) {
        log('PAGE payment/options (XHR) yakalandı');
        captureOptionsReq(this._tgoHeaders || {}, typeof body === 'string' ? body : null);
      }
    } catch (_) {}

    if (!this._tgoIsCartsGet) {
      return _origSend.apply(this, arguments);
    }
    var xhr = this;
    var url = this._tgoUrl;
    var headerObj = headerMapToObject(this._tgoHeaders || {});

    buildMergedCarts(url, headerObj).then(function (res) {
      deliverFakeResponse(xhr, res.status || 200, res.text || '', res.contentType);
    }).catch(function () {
      deliverFakeResponse(xhr, 0, '', null);
    });
  };

  // ─── fetch override (carts fetch ile giderse de çalışsın) ────────────────────
  window.fetch = function (resource, init) {
    var urlStr, method, headerObj = {};

    try {
      if (resource instanceof Request) {
        urlStr = resource.url;
        method = (resource.method || 'GET').toUpperCase();
        if (resource.headers && resource.headers.forEach) {
          resource.headers.forEach(function (v, k) { headerObj[String(k).toLowerCase()] = v; });
        }
      } else {
        urlStr = String(resource);
        method = (init && init.method ? init.method : 'GET').toUpperCase();
        if (init && init.headers) {
          if (init.headers instanceof Headers) {
            init.headers.forEach(function (v, k) { headerObj[String(k).toLowerCase()] = v; });
          } else {
            for (var k in init.headers) {
              if (Object.prototype.hasOwnProperty.call(init.headers, k)) headerObj[String(k).toLowerCase()] = init.headers[k];
            }
          }
        }
      }
      if (headerObj['authorization']) captureAuth(headerObj['authorization']);

      if (method === 'POST' && urlStr && urlStr.indexOf('/v3/payment/options') !== -1) {
        log('PAGE payment/options (fetch) yakalandı');
        var rawBody = (resource instanceof Request) ? null : (init && init.body);
        if (typeof rawBody === 'string') {
          captureOptionsReq(headerObj, rawBody);
        } else if (resource instanceof Request) {
          try { resource.clone().text().then(function (t) { captureOptionsReq(headerObj, t); }); } catch (_) { captureOptionsReq(headerObj, null); }
        } else {
          captureOptionsReq(headerObj, null);
        }
      }
    } catch (_) {}

    if (method === 'GET' && urlStr && isCartsGetUrl(urlStr)) {
      return buildMergedCarts(urlStr, headerObj).then(function (res) {
        return new Response(res.text || '', {
          status: res.status || 200,
          statusText: 'OK',
          headers: { 'content-type': res.contentType || 'application/json; charset=utf-8' }
        });
      });
    }

    return _origFetch.apply(this, arguments);
  };
})();
