import { setSecret } from './secret-store.mjs';

const EBAY_AUTH_SANDBOX = 'https://auth.sandbox.ebay.com/oauth2/authorize';
const EBAY_AUTH_PROD    = 'https://auth.ebay.com/oauth2/authorize';
const EBAY_TOKEN_SANDBOX = 'https://api.sandbox.ebay.com/identity/v1/oauth2/token';
const EBAY_TOKEN_PROD    = 'https://api.ebay.com/identity/v1/oauth2/token';
const EBAY_API_SANDBOX   = 'https://api.sandbox.ebay.com';
const EBAY_API_PROD      = 'https://api.ebay.com';

function isSandbox() {
  return process.env.EBAY_SANDBOX === 'true';
}

function authUrl()  { return isSandbox() ? EBAY_AUTH_SANDBOX  : EBAY_AUTH_PROD; }
function tokenUrl() { return isSandbox() ? EBAY_TOKEN_SANDBOX : EBAY_TOKEN_PROD; }
function apiBase()  { return isSandbox() ? EBAY_API_SANDBOX   : EBAY_API_PROD; }

function setEnvVar(key, value) {
  setSecret(key, value, { source: 'oauth' });
}

function getBasicAuth() {
  const clientId = process.env.EBAY_CLIENT_ID;
  const clientSecret = process.env.EBAY_CLIENT_SECRET;
  if (!clientId || !clientSecret) throw new Error('EBAY_CLIENT_ID oder EBAY_CLIENT_SECRET nicht gesetzt');
  return Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
}

const SCOPES = [
  'https://api.ebay.com/oauth/api_scope',
  'https://api.ebay.com/oauth/api_scope/sell.inventory',
  'https://api.ebay.com/oauth/api_scope/sell.account',
  'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
  'https://api.ebay.com/oauth/api_scope/sell.marketing',
].join(' ');

let oauthState = null;

export function getOAuthUrl(redirectUri) {
  if (!process.env.EBAY_CLIENT_ID) throw new Error('EBAY_CLIENT_ID nicht gesetzt');
  oauthState = Math.random().toString(36).substring(2);

  const params = new URLSearchParams({
    client_id: process.env.EBAY_CLIENT_ID,
    response_type: 'code',
    redirect_uri: process.env.EBAY_RU_NAME || redirectUri,
    scope: SCOPES,
    state: oauthState,
  });
  return `${authUrl()}?${params}`;
}

export async function handleCallback(code, state, redirectUri) {
  if (oauthState && state !== oauthState) throw new Error('Ungültiger OAuth-State');
  oauthState = null;

  const res = await fetch(tokenUrl(), {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${getBasicAuth()}`,
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      redirect_uri: process.env.EBAY_RU_NAME || redirectUri,
    }),
  });

  if (!res.ok) {
    const err = await res.text();
    throw new Error(`eBay Token-Fehler: ${err}`);
  }

  const tokens = await res.json();
  setEnvVar('EBAY_ACCESS_TOKEN', tokens.access_token);
  setEnvVar('EBAY_REFRESH_TOKEN', tokens.refresh_token);
  return tokens;
}

async function refreshToken() {
  const refreshTkn = process.env.EBAY_REFRESH_TOKEN;
  if (!refreshTkn) throw new Error('Kein eBay Refresh-Token');

  const res = await fetch(tokenUrl(), {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${getBasicAuth()}`,
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: refreshTkn,
      scope: SCOPES,
    }),
  });

  if (!res.ok) throw new Error('eBay Token-Refresh fehlgeschlagen');
  const tokens = await res.json();
  setEnvVar('EBAY_ACCESS_TOKEN', tokens.access_token);
  if (tokens.refresh_token) setEnvVar('EBAY_REFRESH_TOKEN', tokens.refresh_token);
  return tokens.access_token;
}

async function ebayFetch(path, opts = {}) {
  let token = process.env.EBAY_ACCESS_TOKEN;
  if (!token) throw new Error('Nicht mit eBay verbunden');

  const headers = {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
    'Content-Language': 'de-DE',
    'X-EBAY-C-MARKETPLACE-ID': 'EBAY_DE',
    ...opts.headers,
  };

  let res = await fetch(`${apiBase()}${path}`, { ...opts, headers });

  if (res.status === 401) {
    token = await refreshToken();
    headers.Authorization = `Bearer ${token}`;
    res = await fetch(`${apiBase()}${path}`, { ...opts, headers });
  }

  if (res.status === 204) return null;

  if (!res.ok) {
    const err = await res.text();
    throw new Error(`eBay API (${res.status}): ${err}`);
  }

  const ct = res.headers.get('content-type') || '';
  return ct.includes('json') ? res.json() : res.text();
}

function mapCondition(condition) {
  const map = {
    'neu': 'NEW', 'new': 'NEW',
    'wie neu': 'LIKE_NEW', 'like new': 'LIKE_NEW',
    'sehr gut': 'VERY_GOOD', 'very good': 'VERY_GOOD',
    'gut': 'GOOD', 'good': 'GOOD',
    'akzeptabel': 'ACCEPTABLE', 'acceptable': 'ACCEPTABLE',
    'defekt': 'FOR_PARTS_OR_NOT_WORKING',
  };
  return map[(condition || '').toLowerCase()] || 'GOOD';
}

export async function createInventoryItem(listing, sku) {
  const images = (listing.photos || []).map(p => `http://localhost:${process.env.PORT || 8124}/uploads/${p}`);

  const item = {
    availability: {
      shipToLocationAvailability: { quantity: 1 },
    },
    condition: mapCondition(listing.condition),
    product: {
      title: listing.title,
      description: listing.description || '',
      aspects: {},
      imageUrls: images,
    },
  };

  if (listing.brand) item.product.aspects['Marke'] = [listing.brand];
  if (listing.color) item.product.aspects['Farbe'] = [listing.color];
  if (listing.size) item.product.aspects['Größe'] = [listing.size];

  await ebayFetch(`/sell/inventory/v1/inventory_item/${encodeURIComponent(sku)}`, {
    method: 'PUT',
    body: JSON.stringify(item),
  });

  return sku;
}

export async function createOffer(listing, sku) {
  const price = listing.price || listing.suggested_price || 1;

  const offer = {
    sku,
    marketplaceId: 'EBAY_DE',
    format: 'FIXED_PRICE',
    listingDescription: listing.description || '',
    availableQuantity: 1,
    pricingSummary: {
      price: { value: String(price), currency: 'EUR' },
    },
    listingPolicies: {},
    merchantLocationKey: process.env.EBAY_LOCATION_KEY || undefined,
  };

  const categoryId = listing.ebay_category_id || process.env.EBAY_DEFAULT_CATEGORY || '175673';
  offer.categoryId = categoryId;

  const fulfillmentId = process.env.EBAY_FULFILLMENT_POLICY_ID;
  const paymentId = process.env.EBAY_PAYMENT_POLICY_ID;
  const returnId = process.env.EBAY_RETURN_POLICY_ID;

  if (fulfillmentId) offer.listingPolicies.fulfillmentPolicyId = fulfillmentId;
  if (paymentId) offer.listingPolicies.paymentPolicyId = paymentId;
  if (returnId) offer.listingPolicies.returnPolicyId = returnId;

  const result = await ebayFetch('/sell/inventory/v1/offer', {
    method: 'POST',
    body: JSON.stringify(offer),
  });

  return result;
}

export async function publishOffer(offerId) {
  const result = await ebayFetch(`/sell/inventory/v1/offer/${offerId}/publish`, {
    method: 'POST',
  });
  return result;
}

export async function createAndPublish(listing, sku) {
  await createInventoryItem(listing, sku);
  const offer = await createOffer(listing, sku);
  const offerId = offer.offerId;
  const published = await publishOffer(offerId);
  return {
    offerId,
    listingId: published.listingId,
    url: `https://www.ebay.de/itm/${published.listingId}`,
  };
}

export async function getFulfillmentPolicies() {
  return ebayFetch('/sell/account/v1/fulfillment_policy?marketplace_id=EBAY_DE');
}

export async function getPaymentPolicies() {
  return ebayFetch('/sell/account/v1/payment_policy?marketplace_id=EBAY_DE');
}

export async function getReturnPolicies() {
  return ebayFetch('/sell/account/v1/return_policy?marketplace_id=EBAY_DE');
}

export async function getPolicies() {
  const [fulfillment, payment, returns] = await Promise.all([
    getFulfillmentPolicies().catch(() => ({ fulfillmentPolicies: [] })),
    getPaymentPolicies().catch(() => ({ paymentPolicies: [] })),
    getReturnPolicies().catch(() => ({ returnPolicies: [] })),
  ]);
  return {
    fulfillment: fulfillment.fulfillmentPolicies || [],
    payment: payment.paymentPolicies || [],
    returns: returns.returnPolicies || [],
  };
}

export function isConnected() {
  return !!(process.env.EBAY_ACCESS_TOKEN && process.env.EBAY_CLIENT_ID);
}

export function hasCredentials() {
  return !!(process.env.EBAY_CLIENT_ID && process.env.EBAY_CLIENT_SECRET);
}

export async function getOffer(offerId) {
  if (!offerId) throw new Error('eBay Offer-ID fehlt');
  return ebayFetch(`/sell/inventory/v1/offer/${encodeURIComponent(offerId)}`);
}

export async function updateOffer(listing, offerId, sku) {
  if (!offerId) throw new Error('eBay Offer-ID fehlt');
  await createInventoryItem(listing, sku);
  const price = listing.price || listing.suggested_price || 1;
  const body = {
    sku,
    marketplaceId: 'EBAY_DE',
    format: 'FIXED_PRICE',
    listingDescription: listing.description || '',
    availableQuantity: 1,
    pricingSummary: { price: { value: String(price), currency: 'EUR' } },
    listingPolicies: {},
    categoryId: listing.ebay_category_id || process.env.EBAY_DEFAULT_CATEGORY || '175673',
    merchantLocationKey: process.env.EBAY_LOCATION_KEY || undefined,
  };
  if (process.env.EBAY_FULFILLMENT_POLICY_ID) body.listingPolicies.fulfillmentPolicyId = process.env.EBAY_FULFILLMENT_POLICY_ID;
  if (process.env.EBAY_PAYMENT_POLICY_ID) body.listingPolicies.paymentPolicyId = process.env.EBAY_PAYMENT_POLICY_ID;
  if (process.env.EBAY_RETURN_POLICY_ID) body.listingPolicies.returnPolicyId = process.env.EBAY_RETURN_POLICY_ID;
  await ebayFetch(`/sell/inventory/v1/offer/${encodeURIComponent(offerId)}`, { method: 'PUT', body: JSON.stringify(body) });
  return getOffer(offerId);
}

export async function withdrawOffer(offerId) {
  if (!offerId) throw new Error('eBay Offer-ID fehlt');
  return ebayFetch(`/sell/inventory/v1/offer/${encodeURIComponent(offerId)}/withdraw`, { method: 'POST' });
}
