import { randomBytes, createHash } from 'crypto';
import { setSecret } from './secret-store.mjs';

const ETSY_BASE = 'https://api.etsy.com/v3';
const ETSY_AUTH = 'https://www.etsy.com/oauth/connect';
const ETSY_TOKEN = 'https://api.etsy.com/v3/public/oauth/token';

let pkceStore = {};

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

function generatePKCE() {
  const verifier = randomBytes(32).toString('base64url');
  const challenge = createHash('sha256').update(verifier).digest('base64url');
  return { verifier, challenge };
}

export function getAuthUrl(redirectUri) {
  const apiKey = process.env.ETSY_API_KEY;
  if (!apiKey) throw new Error('ETSY_API_KEY nicht gesetzt');

  const { verifier, challenge } = generatePKCE();
  const state = randomBytes(16).toString('hex');
  pkceStore[state] = verifier;

  const params = new URLSearchParams({
    response_type: 'code',
    client_id: apiKey,
    redirect_uri: redirectUri,
    scope: 'listings_w listings_r shops_r images_w',
    state,
    code_challenge: challenge,
    code_challenge_method: 'S256',
  });

  return `${ETSY_AUTH}?${params}`;
}

export async function handleCallback(code, state, redirectUri) {
  const verifier = pkceStore[state];
  if (!verifier) throw new Error('Ungültiger OAuth-State');
  delete pkceStore[state];

  const apiKey = process.env.ETSY_API_KEY;
  const res = await fetch(ETSY_TOKEN, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: apiKey,
      redirect_uri: redirectUri,
      code,
      code_verifier: verifier,
    }),
  });

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

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

async function refreshToken() {
  const apiKey = process.env.ETSY_API_KEY;
  const refreshToken = process.env.ETSY_REFRESH_TOKEN;
  if (!refreshToken) throw new Error('Kein Etsy Refresh-Token');

  const res = await fetch(ETSY_TOKEN, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: apiKey,
      refresh_token: refreshToken,
    }),
  });

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

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

  const apiKey = process.env.ETSY_API_KEY;
  const headers = { 'x-api-key': apiKey, Authorization: `Bearer ${token}`, ...opts.headers };
  let res = await fetch(`${ETSY_BASE}${path}`, { ...opts, headers });

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

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

export async function getShopId() {
  const data = await etsyFetch('/application/users/me');
  const userId = data.user_id;
  const shop = await etsyFetch(`/application/users/${userId}/shops`);
  if (!shop.results?.length) throw new Error('Kein Etsy-Shop gefunden');
  return shop.results[0].shop_id;
}

export async function createEtsyListing(listing, shopId) {
  const tags = Array.isArray(listing.tags) ? listing.tags.slice(0, 13) : [];
  const price = listing.price || listing.suggested_price || 10;

  const body = {
    quantity: 1,
    title: listing.title,
    description: listing.description,
    price: price,
    who_made: 'someone_else',
    when_made: '2020_2025',
    taxonomy_id: 1,
    tags,
    type: 'physical',
    shipping_profile_id: null,
    state: 'draft',
  };

  const result = await etsyFetch(`/application/shops/${shopId}/listings`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });

  return result;
}

export async function uploadEtsyImage(shopId, listingId, imageBuffer, filename) {
  const formData = new FormData();
  formData.append('image', new Blob([imageBuffer]), filename);

  const token = process.env.ETSY_ACCESS_TOKEN;
  const apiKey = process.env.ETSY_API_KEY;

  const res = await fetch(`${ETSY_BASE}/application/shops/${shopId}/listings/${listingId}/images`, {
    method: 'POST',
    headers: {
      'x-api-key': apiKey,
      Authorization: `Bearer ${token}`,
    },
    body: formData,
  });

  if (!res.ok) {
    const err = await res.text();
    throw new Error(`Bild-Upload fehlgeschlagen: ${err}`);
  }
  return res.json();
}

export function isConnected() {
  return !!(process.env.ETSY_ACCESS_TOKEN && process.env.ETSY_API_KEY);
}

export async function getEtsyListing(listingId) {
  if (!listingId) throw new Error('Etsy Listing-ID fehlt');
  return etsyFetch(`/application/listings/${encodeURIComponent(listingId)}`);
}
