import { FastifyReply, FastifyRequest } from 'fastify';
import { request as undiciRequest } from 'undici';

import { config } from '../config';
import { buildUpstreamHeaders } from '../proxy/headers';

export interface CheckoutCustomer {
  firstname: string;
  lastname: string;
  email: string;
  phone: string;
}

export interface CheckoutSessionResponse {
  loggedIn: boolean;
  customer?: CheckoutCustomer;
}

function parseCustomerSection(body: string): CheckoutCustomer | undefined {
  try {
    const json = JSON.parse(body) as {
      customer?: {
        firstname?: string;
        lastname?: string;
        email?: string;
        telephone?: string;
      };
    };
    const c = json.customer;
    if (!c?.email) return undefined;
    return {
      firstname: String(c.firstname ?? '').trim(),
      lastname: String(c.lastname ?? '').trim(),
      email: String(c.email ?? '').trim(),
      phone: String(c.telephone ?? '').trim(),
    };
  } catch {
    return undefined;
  }
}

/** Probe Magento customer section — requires valid Sinsay session cookies. */
async function fetchCustomerFromUpstream(
  request: FastifyRequest,
): Promise<CheckoutCustomer | undefined> {
  const headers = buildUpstreamHeaders(
    request.headers as Record<string, string | string[] | undefined>,
    'www.sinsay.com',
  );
  headers.accept = 'application/json, text/plain, */*';

  const upstream = await undiciRequest(
    `${config.upstream.main}/pl/pl/customer/section/load/?sections=customer&force_new_section_timestamp=true`,
    {
      method: 'GET',
      headers,
      throwOnError: false,
      headersTimeout: 8_000,
      bodyTimeout: 8_000,
    },
  );

  const chunks: Buffer[] = [];
  for await (const chunk of upstream.body) {
    chunks.push(chunk instanceof Buffer ? chunk : Buffer.from(chunk));
  }
  if (upstream.statusCode !== 200) return undefined;
  return parseCustomerSection(Buffer.concat(chunks).toString('utf8'));
}

export async function resolveCheckoutSession(
  request: FastifyRequest,
): Promise<CheckoutSessionResponse> {
  const cookies = request.cookies as Record<string, string>;
  const hasFrontend = Boolean(cookies['frontend']);

  try {
    const customer = await fetchCustomerFromUpstream(request);
    if (customer?.email) {
      return { loggedIn: true, customer };
    }
  } catch {
    /* upstream timeout or error */
  }

  // Magento frontend cookie present but section load failed — still show checkout UI
  if (hasFrontend) {
    return { loggedIn: true };
  }

  return { loggedIn: false };
}

export async function handleCheckoutSession(
  request: FastifyRequest,
  reply: FastifyReply,
): Promise<void> {
  const session = await resolveCheckoutSession(request);
  reply.send(session);
}
