import type { SupabaseClient, User } from "@supabase/supabase-js";
import { getCompanyProfile } from "@/lib/api-v1/services/company-service";
import { findCustomerByPhone, type CustomerSummary } from "@/lib/api-v1/services/customer-service";
import { listCustomerOrders, listOrderItemsByOrderIds, type OrderItemSummary, type OrderSummary } from "@/lib/api-v1/services/orders-service";
import { listFeaturedProducts, listProductsByIds } from "@/lib/api-v1/services/products-service";
import { listQuoteItemsByQuoteIds, listQuotesByCustomer, type QuoteItemSummary, type QuoteListItem } from "@/lib/api-v1/services/quotes-service";

type ExtensionProduct = Awaited<ReturnType<typeof listFeaturedProducts>>["data"][number];

type ProductInsight = {
  product_id: string | null;
  product_name: string;
  quantity: number;
  total_amount: number;
  sources: string[];
  product: ExtensionProduct | null;
};

function sumNumbers(values: number[]) {
  return values.reduce((total, value) => total + value, 0);
}

function normalizeMoney(value: number) {
  return Number(value.toFixed(2));
}

function getLatestDate(values: Array<string | null | undefined>) {
  const timestamps = values
    .map((value) => (value ? new Date(value).getTime() : 0))
    .filter((value) => Number.isFinite(value) && value > 0);

  if (!timestamps.length) return null;
  return new Date(Math.max(...timestamps)).toISOString();
}

function getCurrentCustomerStatus(customer: CustomerSummary, orders: OrderSummary[], quotes: QuoteListItem[]) {
  if (!customer.active) {
    return {
      code: "inactive",
      label: "Cliente inativo",
    };
  }

  if (orders.length > 0) {
    return {
      code: "customer",
      label: "Cliente com compras",
    };
  }

  if (quotes.length > 0) {
    return {
      code: "lead_with_quotes",
      label: "Lead com orcamentos",
    };
  }

  return {
    code: "new_lead",
    label: "Lead sem historico comercial",
  };
}

function buildCommercialStats(customer: CustomerSummary, orders: OrderSummary[], quotes: QuoteListItem[]) {
  const totalPurchased = normalizeMoney(sumNumbers(orders.map((order) => order.total_amount)));
  const averageTicket = orders.length > 0 ? normalizeMoney(totalPurchased / orders.length) : 0;

  return {
    orders_count: orders.length,
    quotes_count: quotes.length,
    total_purchased: totalPurchased,
    average_ticket: averageTicket,
    last_purchase_at: orders[0]?.created_at || null,
    last_quote_at: quotes[0]?.created_at || null,
    last_interaction_at: getLatestDate([orders[0]?.created_at, quotes[0]?.created_at]),
    current_status: getCurrentCustomerStatus(customer, orders, quotes),
  };
}

function buildProductInsights(
  orderItems: OrderItemSummary[],
  quoteItems: QuoteItemSummary[],
  products: ExtensionProduct[]
) {
  const productMap = new Map(products.map((product) => [product.id, product]));
  const grouped = new Map<
    string,
    {
      product_id: string | null;
      product_name: string;
      quantity: number;
      total_amount: number;
      sources: Set<string>;
    }
  >();

  for (const item of orderItems) {
    const key = item.product_id || `order-title:${item.title}`;
    const current = grouped.get(key) || {
      product_id: item.product_id,
      product_name: item.title,
      quantity: 0,
      total_amount: 0,
      sources: new Set<string>(),
    };
    current.quantity += Number(item.quantity || 0);
    current.total_amount += Number(item.total_price || 0);
    current.sources.add("order");
    if (item.product_id && productMap.get(item.product_id)?.name) {
      current.product_name = productMap.get(item.product_id)?.name || current.product_name;
    }
    grouped.set(key, current);
  }

  for (const item of quoteItems) {
    const key = item.product_id || `quote-title:${item.title}`;
    const current = grouped.get(key) || {
      product_id: item.product_id,
      product_name: item.title,
      quantity: 0,
      total_amount: 0,
      sources: new Set<string>(),
    };
    current.quantity += Number(item.quantity || 0);
    current.total_amount += Number(item.total_price || 0);
    current.sources.add("quote");
    if (item.product_id && productMap.get(item.product_id)?.name) {
      current.product_name = productMap.get(item.product_id)?.name || current.product_name;
    }
    grouped.set(key, current);
  }

  return Array.from(grouped.values())
    .map<ProductInsight>((entry) => ({
      product_id: entry.product_id,
      product_name: entry.product_name,
      quantity: entry.quantity,
      total_amount: normalizeMoney(entry.total_amount),
      sources: Array.from(entry.sources.values()),
      product: entry.product_id ? productMap.get(entry.product_id) || null : null,
    }))
    .sort((a, b) => {
      if (b.quantity !== a.quantity) return b.quantity - a.quantity;
      return b.total_amount - a.total_amount;
    });
}

async function loadExtensionBaseContext(params: { supabase: SupabaseClient; user: User; phone: string }) {
  const [companyResult, customerLookup] = await Promise.all([
    getCompanyProfile({ supabase: params.supabase, user: params.user }),
    findCustomerByPhone({ supabase: params.supabase, user: params.user, phone: params.phone }),
  ]);

  if (!customerLookup.customer) {
    return {
      phone: customerLookup.normalized_phone,
      company: companyResult.data,
      customer: null,
      quotes: [] as QuoteListItem[],
      orders: [] as OrderSummary[],
      quoteItems: [] as QuoteItemSummary[],
      orderItems: [] as OrderItemSummary[],
      topProducts: [] as ProductInsight[],
    };
  }

  const customer = customerLookup.customer;
  const [quotesResult, ordersResult] = await Promise.all([
    listQuotesByCustomer({
      supabase: params.supabase,
      user: params.user,
      clientId: customer.id,
    }),
    listCustomerOrders({
      supabase: params.supabase,
      user: params.user,
      clientId: customer.id,
    }),
  ]);

  const quoteIds = quotesResult.data.map((quote) => quote.id);
  const orderIds = ordersResult.data.map((order) => order.id);
  const [quoteItemsResult, orderItemsResult] = await Promise.all([
    listQuoteItemsByQuoteIds({
      supabase: params.supabase,
      user: params.user,
      quoteIds,
    }),
    listOrderItemsByOrderIds({
      supabase: params.supabase,
      user: params.user,
      orderIds,
    }),
  ]);

  const productIds = Array.from(
    new Set(
      [...quoteItemsResult.data, ...orderItemsResult.data]
        .map((item) => item.product_id)
        .filter((productId): productId is string => Boolean(productId))
    )
  );

  const productsResult = productIds.length
    ? await listProductsByIds({
        supabase: params.supabase,
        user: params.user,
        ids: productIds,
      })
    : { ok: true as const, data: [] as ExtensionProduct[] };

  const topProducts = buildProductInsights(orderItemsResult.data, quoteItemsResult.data, productsResult.data);

  return {
    phone: customerLookup.normalized_phone,
    company: companyResult.data,
    customer,
    quotes: quotesResult.data,
    orders: ordersResult.data,
    quoteItems: quoteItemsResult.data,
    orderItems: orderItemsResult.data,
    topProducts,
  };
}

export async function getExtensionCustomerContext(params: {
  supabase: SupabaseClient;
  user: User;
  phone: string;
}) {
  const base = await loadExtensionBaseContext(params);

  if (!base.customer) {
    return {
      ok: true,
      data: {
        phone: base.phone,
        customer_found: false,
        customer: null,
        company: base.company,
        recent_quotes: [],
        recent_orders: [],
        top_products: [],
        commercial_stats: {
          orders_count: 0,
          quotes_count: 0,
          total_purchased: 0,
          average_ticket: 0,
          last_purchase_at: null,
          last_quote_at: null,
          last_interaction_at: null,
          current_status: {
            code: "not_found",
            label: "Cliente nao encontrado",
          },
        },
      },
    };
  }

  return {
    ok: true,
    data: {
      phone: base.phone,
      customer_found: true,
      customer: base.customer,
      company: base.company,
      recent_quotes: base.quotes.slice(0, 5),
      recent_orders: base.orders.slice(0, 5),
      top_products: base.topProducts.slice(0, 5),
      commercial_stats: buildCommercialStats(base.customer, base.orders, base.quotes),
    },
  };
}

export async function getExtensionConversationContext(params: {
  supabase: SupabaseClient;
  user: User;
  phone: string;
}) {
  const base = await loadExtensionBaseContext(params);

  let relatedProducts = base.topProducts
    .map((entry) => ({
      product_id: entry.product_id,
      interactions: {
        quantity: entry.quantity,
        total_amount: entry.total_amount,
        sources: entry.sources,
      },
      product: entry.product,
      product_name: entry.product?.name || entry.product_name,
    }))
    .filter((entry) => entry.product || entry.product_name)
    .slice(0, 6);

  if (!relatedProducts.length) {
    const fallbackProducts = await listFeaturedProducts({
      supabase: params.supabase,
      user: params.user,
      limit: 6,
    });

    relatedProducts = fallbackProducts.data.map((product) => ({
      product_id: product.id,
      interactions: {
        quantity: 0,
        total_amount: 0,
        sources: ["catalog"],
      },
      product,
      product_name: product.name,
    }));
  }

  const commercialHistory = base.customer
    ? {
        total_orders: base.orders.length,
        total_quotes: base.quotes.length,
        total_purchased: normalizeMoney(sumNumbers(base.orders.map((order) => order.total_amount))),
        average_ticket: base.orders.length
          ? normalizeMoney(sumNumbers(base.orders.map((order) => order.total_amount)) / base.orders.length)
          : 0,
        latest_interaction_at: getLatestDate([base.orders[0]?.created_at, base.quotes[0]?.created_at]),
        top_products: base.topProducts.slice(0, 5),
      }
    : {
        total_orders: 0,
        total_quotes: 0,
        total_purchased: 0,
        average_ticket: 0,
        latest_interaction_at: null,
        top_products: [],
      };

  return {
    ok: true,
    data: {
      phone: base.phone,
      customer_found: Boolean(base.customer),
      customer: base.customer,
      recent_quotes: base.quotes.slice(0, 5),
      recent_orders: base.orders.slice(0, 5),
      related_products: relatedProducts,
      commercial_history: commercialHistory,
      suggestions_available: {
        can_view_customer: Boolean(base.customer),
        can_review_recent_quotes: base.quotes.length > 0,
        can_review_recent_orders: base.orders.length > 0,
        can_suggest_products: relatedProducts.length > 0,
        can_prepare_quote: Boolean(base.customer),
      },
    },
  };
}
