import { createClient } from "@/lib/supabase-server";
import { NextResponse } from "next/server";

export const dynamic = "force-dynamic";

type ShippingProviderId = "melhor_envio" | "superfrete";

type UnifiedShippingOption = {
  id: string;
  provider: ShippingProviderId;
  provider_label: string;
  name: string;
  service: string;
  price: number;
  delivery_time: number;
  logo_url?: string;
  currency?: string;
};

type MelhorEnvioCompany = {
  name: string;
  picture: string | null;
};

type MelhorEnvioOption = {
  id: string | number;
  name: string;
  price: string | number;
  delivery_time: number;
  currency: string;
  error?: string | boolean | null;
  company: MelhorEnvioCompany;
};

function isMelhorEnvioOption(value: unknown): value is MelhorEnvioOption {
  if (!value || typeof value !== "object") return false;
  const record = value as Record<string, unknown>;
  const company = record.company as Record<string, unknown> | undefined;
  return typeof record.id !== "undefined" &&
    typeof record.name === "string" &&
    typeof record.price !== "undefined" &&
    typeof record.delivery_time === "number" &&
    typeof record.currency === "string" &&
    typeof company?.name === "string";
}

function sanitizePostalCode(value: unknown) {
  return String(value ?? "").replace(/\D/g, "").slice(0, 8);
}

function parsePositiveNumber(value: unknown, fallback: number, min: number) {
  const parsed = Number(value);
  if (!Number.isFinite(parsed)) return fallback;
  return Math.max(min, parsed);
}

function extractDeliveryTime(value: unknown) {
  if (typeof value === "number" && Number.isFinite(value) && value >= 0) return Math.round(value);
  if (typeof value === "string") {
    const parsed = Number(value);
    if (Number.isFinite(parsed) && parsed >= 0) return Math.round(parsed);
  }
  if (value && typeof value === "object") {
    const record = value as Record<string, unknown>;
    const min = Number(record.min);
    const max = Number(record.max);
    if (Number.isFinite(min) && min >= 0) return Math.round(min);
    if (Number.isFinite(max) && max >= 0) return Math.round(max);
  }
  return null;
}

function parseProviderErrorMessage(raw: string, providerLabel: string) {
  const trimmed = raw.trim();
  if (!trimmed) return `Erro ao consultar ${providerLabel}.`;
  try {
    const parsed = JSON.parse(trimmed) as { message?: unknown; error?: unknown; errors?: Record<string, unknown> };
    const directMessage =
      typeof parsed.message === "string"
        ? parsed.message
        : typeof parsed.error === "string"
        ? parsed.error
        : "";
    if (parsed.errors && typeof parsed.errors === "object") {
      const entries = Object.entries(parsed.errors);
      for (const [, value] of entries) {
        if (Array.isArray(value)) {
          const first = value.find((item) => typeof item === "string");
          if (typeof first === "string" && first.trim()) return first.trim();
        }
        if (typeof value === "string" && value.trim()) return value.trim();
      }
    }
    if (directMessage.trim()) return directMessage.trim();
  } catch {
    return trimmed;
  }
  return `Erro ao consultar ${providerLabel}.`;
}

function isNoResultError(raw: string) {
  const message = raw.toLowerCase();
  if (message.includes("no_result")) return true;
  try {
    const parsed = JSON.parse(raw) as { errors?: Record<string, unknown> };
    const errors = parsed?.errors;
    if (!errors || typeof errors !== "object") return false;
    return Object.keys(errors).some((key) => key.toLowerCase().includes("no_result"));
  } catch {
    return false;
  }
}

function isServicesRequiredError(raw: string) {
  const message = raw.toLowerCase();
  return message.includes("services") && (message.includes("obrigatorio") || message.includes("obrigatório"));
}

function extractServiceIdsFromUnknown(value: unknown, bucket: Set<number>) {
  if (!value || bucket.size >= 40) return;
  if (Array.isArray(value)) {
    value.forEach((item) => extractServiceIdsFromUnknown(item, bucket));
    return;
  }
  if (typeof value !== "object") return;
  const record = value as Record<string, unknown>;
  const idCandidate = record.id ?? record.service_id ?? record.code;
  const idNumber = Number(idCandidate);
  if (Number.isFinite(idNumber) && idNumber > 0) {
    bucket.add(Math.trunc(idNumber));
  }
  Object.values(record).forEach((item) => extractServiceIdsFromUnknown(item, bucket));
}

async function fetchSuperFreteServiceIds(baseUrl: string, token: string) {
  const endpoints = [
    "/api/v0/services",
    "/api/v0/calculator/services",
    "/api/v0/freight/services",
  ];
  const baseOrigin = baseUrl.startsWith("https://api.superfrete.com")
    ? "https://api.superfrete.com"
    : "https://sandbox.superfrete.com";
  const ids = new Set<number>();

  for (const endpoint of endpoints) {
    try {
      const response = await fetch(`${baseOrigin}${endpoint}`, {
        method: "GET",
        headers: {
          "Accept": "application/json",
          "Authorization": `Bearer ${token}`,
          "User-Agent": "Ktalogu (integracao@ktalogu.com.br)",
        },
      });
      if (!response.ok) continue;
      const raw = (await response.json()) as unknown;
      extractServiceIdsFromUnknown(raw, ids);
      if (ids.size > 0) break;
    } catch {
      continue;
    }
  }

  return Array.from(ids).slice(0, 20);
}

function mapSuperFreteOptions(rawData: unknown): UnifiedShippingOption[] {
  const getCarrierFallbackLogo = (carrierName: string) => {
    const value = carrierName.toLowerCase();
    if (value.includes("correios")) return "https://www.correios.com.br/favicon.ico";
    if (value.includes("jadlog")) return "https://www.jadlog.com.br/favicon.ico";
    if (value.includes("loggi")) return "https://www.loggi.com/favicon.ico";
    return undefined;
  };

  const asArray = Array.isArray(rawData)
    ? rawData
    : (rawData && typeof rawData === "object" && Array.isArray((rawData as { data?: unknown[] }).data))
    ? (rawData as { data: unknown[] }).data
    : [];

  const options: UnifiedShippingOption[] = [];

  asArray.forEach((item, index) => {
    if (!item || typeof item !== "object") return;
    const record = item as Record<string, unknown>;
    const id = record.id ?? record.service_id ?? record.uuid ?? index;
    const service = typeof record.name === "string"
      ? record.name
      : typeof record.service === "string"
      ? record.service
      : "Serviço";
    const companyRaw = record.company;
    const companyName =
      companyRaw && typeof companyRaw === "object" && typeof (companyRaw as Record<string, unknown>).name === "string"
        ? String((companyRaw as Record<string, unknown>).name)
        : typeof record.company_name === "string"
        ? String(record.company_name)
        : "SuperFrete";
    const companyPicture =
      companyRaw && typeof companyRaw === "object" && typeof (companyRaw as Record<string, unknown>).picture === "string"
        ? String((companyRaw as Record<string, unknown>).picture)
        : companyRaw && typeof companyRaw === "object" && typeof (companyRaw as Record<string, unknown>).logo === "string"
        ? String((companyRaw as Record<string, unknown>).logo)
        : undefined;
    const priceCandidate = record.price ?? record.custom_price ?? record.total_price ?? record.shipping_price;
    const price = Number(priceCandidate);
    const deliveryTime = extractDeliveryTime(record.delivery_time ?? record.delivery_range ?? record.delivery_days);
    if (!Number.isFinite(price) || price < 0 || deliveryTime === null) return;

    options.push({
      id: String(id),
      provider: "superfrete",
      provider_label: "SuperFrete",
      name: companyName,
      service,
      price,
      delivery_time: deliveryTime,
      logo_url:
        (typeof record.picture === "string" ? record.picture : undefined) ||
        companyPicture ||
        getCarrierFallbackLogo(companyName),
      currency: typeof record.currency === "string" ? record.currency : "BRL",
    });
  });

  return options;
}

export async function POST(request: Request) {
  try {
    const supabase = await createClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();

    if (!user) {
      return NextResponse.json({ error: "Não autorizado" }, { status: 401 });
    }

    const body = await request.json();
    const { zip, weight, width, height, length } = body;

    const destinationZip = sanitizePostalCode(zip);
    const packageWeight = parsePositiveNumber(weight, 1, 0.1);
    const packageWidth = parsePositiveNumber(width, 20, 1);
    const packageHeight = parsePositiveNumber(height, 20, 1);
    const packageLength = parsePositiveNumber(length, 20, 1);

    if (!destinationZip || destinationZip.length < 8) {
      return NextResponse.json(
        { error: "Dados incompletos para cotação." },
        { status: 400 }
      );
    }

    const { data: integrations } = await supabase
      .from("integrations")
      .select("provider, token, settings")
      .eq("user_id", user.id)
      .in("provider", ["melhor_envio", "superfrete"])
      .eq("active", true)
      ;

    const byProvider = new Map<string, { token?: string; settings?: Record<string, unknown> }>();
    (integrations || []).forEach((integration) => {
      byProvider.set(integration.provider, {
        token: integration.token || undefined,
        settings: (integration.settings as Record<string, unknown> | undefined) || {},
      });
    });

    if (!byProvider.get("melhor_envio") && !byProvider.get("superfrete")) {
      return NextResponse.json(
        { error: "Nenhuma integração de frete configurada. Acesse Configurações > Integrações." },
        { status: 400 }
      );
    }

    const { data: profile } = await supabase
      .from("profiles")
      .select("address, zip_code")
      .eq("id", user.id)
      .maybeSingle();

    const profileZip = sanitizePostalCode(profile?.zip_code);
    const profileAddressZipMatch = profile?.address
      ? sanitizePostalCode((String(profile.address).match(/(\d{8})/) || [])[0] || "")
      : "";
    const fallbackOriginZip = profileZip || profileAddressZipMatch || "01001000";

    const providerResults: Array<{
      provider: ShippingProviderId;
      provider_label: string;
      configured: boolean;
      options: UnifiedShippingOption[];
      error?: string;
    }> = [];

    const melhorEnvioIntegration = byProvider.get("melhor_envio");
    if (melhorEnvioIntegration?.token) {
      const env = String(melhorEnvioIntegration.settings?.env || "sandbox") === "production" ? "production" : "sandbox";
      const fromZip = sanitizePostalCode(melhorEnvioIntegration.settings?.origin_zip) || fallbackOriginZip;
      const baseUrl = env === "production"
        ? "https://melhorenvio.com.br/api/v2/me/shipment/calculate"
        : "https://sandbox.melhorenvio.com.br/api/v2/me/shipment/calculate";

      const melhorEnvioPayload = {
        from: { postal_code: fromZip },
        to: { postal_code: destinationZip },
        package: {
          height: packageHeight,
          width: packageWidth,
          length: packageLength,
          weight: packageWeight,
        },
        options: {
          insurance_value: 0,
          receipt: false,
          own_hand: false,
        },
      };

      try {
        const response = await fetch(baseUrl, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": `Bearer ${melhorEnvioIntegration.token}`,
            "User-Agent": "Ktalogu/1.0 (integracao@ktalogu.com.br)",
          },
          body: JSON.stringify(melhorEnvioPayload),
        });

        if (!response.ok) {
          const errorText = await response.text();
          const message = parseProviderErrorMessage(errorText, "Melhor Envio");
          providerResults.push({
            provider: "melhor_envio",
            provider_label: "Melhor Envio",
            configured: true,
            options: [],
            error: message,
          });
        } else {
          const rawData = (await response.json()) as unknown;
          const options = (Array.isArray(rawData) ? rawData : [rawData])
            .filter(isMelhorEnvioOption)
            .filter((opt) => !opt.error)
            .map((opt) => ({
              id: String(opt.id),
              provider: "melhor_envio" as const,
              provider_label: "Melhor Envio",
              name: opt.company.name,
              service: opt.name,
              price: Number(opt.price),
              delivery_time: opt.delivery_time,
              logo_url: opt.company.picture || undefined,
              currency: opt.currency,
            }))
            .filter((option) => Number.isFinite(option.price) && option.price >= 0);

          providerResults.push({
            provider: "melhor_envio",
            provider_label: "Melhor Envio",
            configured: true,
            options,
          });
        }
      } catch (error) {
        providerResults.push({
          provider: "melhor_envio",
          provider_label: "Melhor Envio",
          configured: true,
          options: [],
          error: error instanceof Error ? error.message : "Erro ao consultar Melhor Envio.",
        });
      }
    }

    const superFreteIntegration = byProvider.get("superfrete");
    if (superFreteIntegration?.token) {
      const preferredEnv = String(superFreteIntegration.settings?.env || "sandbox") === "production" ? "production" : "sandbox";
      const envAttempts = preferredEnv === "production" ? (["production", "sandbox"] as const) : (["sandbox", "production"] as const);
      const fromZip = sanitizePostalCode(superFreteIntegration.settings?.origin_zip) || fallbackOriginZip;
      const weightInGrams = Math.max(1, Math.round(packageWeight * 1000));

      try {
        let lastErrorMessage = "Erro ao consultar SuperFrete.";
        let resolvedOptions: UnifiedShippingOption[] = [];

        for (const envAttempt of envAttempts) {
          const baseUrl = envAttempt === "production"
            ? "https://api.superfrete.com/api/v0/calculator"
            : "https://sandbox.superfrete.com/api/v0/calculator";
          const discoveredServiceIds = await fetchSuperFreteServiceIds(baseUrl, superFreteIntegration.token);
          const serviceIds = discoveredServiceIds.length > 0 ? discoveredServiceIds : [1, 2, 17];
          const payloadAttempts = [
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              package: {
                height: packageHeight,
                width: packageWidth,
                length: packageLength,
                weight: packageWeight,
              },
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              package: {
                height: packageHeight,
                width: packageWidth,
                length: packageLength,
                weight: packageWeight,
              },
              services: serviceIds,
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              package: {
                height: packageHeight,
                width: packageWidth,
                length: packageLength,
                weight: weightInGrams,
              },
              services: serviceIds,
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              package: {
                height: packageHeight,
                width: packageWidth,
                length: packageLength,
                weight: packageWeight,
              },
              services: serviceIds.join(","),
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              package: {
                height: packageHeight,
                width: packageWidth,
                length: packageLength,
                weight: weightInGrams,
              },
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              products: [
                {
                  id: "1",
                  width: packageWidth,
                  height: packageHeight,
                  length: packageLength,
                  weight: packageWeight,
                  insurance_value: 0,
                  quantity: 1,
                },
              ],
              services: serviceIds,
            },
            {
              from: { postal_code: fromZip },
              to: { postal_code: destinationZip },
              products: [
                {
                  id: "1",
                  width: packageWidth,
                  height: packageHeight,
                  length: packageLength,
                  weight: weightInGrams,
                  insurance_value: 0,
                  quantity: 1,
                },
              ],
              services: serviceIds,
            },
          ];

          for (const payload of payloadAttempts) {
            const response = await fetch(baseUrl, {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
                "Accept": "application/json",
                "Authorization": `Bearer ${superFreteIntegration.token}`,
                "User-Agent": "Ktalogu (integracao@ktalogu.com.br)",
              },
              body: JSON.stringify(payload),
            });

            if (!response.ok) {
              const errorText = await response.text();
              const parsedMessage = parseProviderErrorMessage(errorText, "SuperFrete");
              lastErrorMessage = parsedMessage.startsWith("Erro ao consultar SuperFrete")
                ? `${parsedMessage} (HTTP ${response.status})`
                : parsedMessage;
              if (isNoResultError(errorText) || isServicesRequiredError(errorText)) {
                continue;
              }
              if (response.status === 401 || response.status === 403) {
                break;
              }
              continue;
            }

            const rawData = (await response.json()) as unknown;
            const mappedOptions = mapSuperFreteOptions(rawData);
            if (mappedOptions.length > 0) {
              resolvedOptions = mappedOptions;
              break;
            }
          }

          if (resolvedOptions.length > 0) break;
        }

        if (resolvedOptions.length > 0) {
          providerResults.push({
            provider: "superfrete",
            provider_label: "SuperFrete",
            configured: true,
            options: resolvedOptions,
          });
        } else {
          providerResults.push({
            provider: "superfrete",
            provider_label: "SuperFrete",
            configured: true,
            options: [],
            error: lastErrorMessage,
          });
        }
      } catch (error) {
        providerResults.push({
          provider: "superfrete",
          provider_label: "SuperFrete",
          configured: true,
          options: [],
          error: error instanceof Error ? error.message : "Erro ao consultar SuperFrete.",
        });
      }
    }

    if (providerResults.length === 0) {
      return NextResponse.json(
        { error: "Nenhuma integração de frete ativa para cotação." },
        { status: 400 }
      );
    }

    const hasAnyOptions = providerResults.some((provider) => provider.options.length > 0);
    if (!hasAnyOptions) {
      const firstError = providerResults.find((provider) => provider.error)?.error || "Nenhuma opção de frete encontrada para este CEP/Dimensões.";
      return NextResponse.json({
        error: firstError,
        providers: providerResults,
      });
    }

    return NextResponse.json({ providers: providerResults });

  } catch (err) {
    console.error("Erro interno na cotação:", err);
    return NextResponse.json(
      { error: "Erro interno ao processar cotação." },
      { status: 500 }
    );
  }
}
