import type { Metadata } from "next";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
import ClientPortalDashboard from "@/components/ClientPortalDashboard";
import { createAdminClient } from "@/lib/supabase-admin";
import { carregarLoja } from "@/lib/loja/dados-da-loja";
import { lerVisaoDaLoja } from "@/lib/loja/visao.server";
import { semPrecosNaLista } from "@/lib/loja/regras-da-loja";
import { getClientPortalOrderDetails, type ClientPortalOrderDetails } from "@/lib/client-portal-order-details";
import { FavoriteProduct, ReviewHistoryItem } from "@/components/client-portal/sections";
import type { SectionId } from "@/components/client-portal/shared";
import { applyPreferredAddressToClient } from "@/lib/client-portal-addresses";

async function resolveClientAvatarUrl(rawValue: string | null | undefined) {
  const value = String(rawValue || "").trim();
  if (!value) return null;
  if (value.startsWith("data:")) return value;

  const parseStorageTarget = (input: string): { bucket: string; path: string } | null => {
    const normalized = input.replace(/^\/+/, "");

    if (/^https?:\/\//i.test(input)) {
      try {
        const parsed = new URL(input);
        const publicMarker = "/storage/v1/object/public/";
        const signMarker = "/storage/v1/object/sign/";
        const marker = parsed.pathname.includes(signMarker) ? signMarker : publicMarker;
        if (!parsed.pathname.includes(marker)) return null;
        const rest = parsed.pathname.slice(parsed.pathname.indexOf(marker) + marker.length);
        const [bucket, ...parts] = rest.split("/");
        return bucket && parts.length ? { bucket, path: parts.join("/") } : null;
      } catch {
        return null;
      }
    }

    const clean = normalized.replace(/^storage\/v1\/object\/public\//, "").replace(/^storage\/v1\/object\/sign\//, "");
    const [bucket, ...parts] = clean.split("/");
    return bucket && parts.length ? { bucket, path: parts.join("/") } : null;
  };

  const target = parseStorageTarget(value);
  if (!target) return value;

  try {
    const admin = createAdminClient();
    const { data: signedData, error: signedError } = await admin.storage
      .from(target.bucket)
      .createSignedUrl(target.path, 60 * 60 * 24 * 30);

    if (!signedError && signedData?.signedUrl) return signedData.signedUrl;

    const { data: publicData } = admin.storage.from(target.bucket).getPublicUrl(target.path);
    return publicData?.publicUrl || value;
  } catch {
    return value;
  }
}

type SessionPayload = {
  profile?: {
    slug?: string | null;
    store_name?: string | null;
    catalog_name?: string | null;
  };
  client?: {
    id: string;
    name: string;
    company_name?: string | null;
    email?: string | null;
    avatar_url?: string | null;
    phone?: string | null;
    whatsapp?: string | null;
    document?: string | null;
    address_zip?: string | null;
    address_street?: string | null;
    address_number?: string | null;
    address_complement?: string | null;
    address_neighborhood?: string | null;
    address_city?: string | null;
    address_state?: string | null;
    notes?: string | null;
    portal_last_login_at?: string | null;
    addresses?: Array<{
      id: string;
      label?: string | null;
      recipient_name?: string | null;
      phone?: string | null;
      zip?: string | null;
      street?: string | null;
      number?: string | null;
      complement?: string | null;
      neighborhood?: string | null;
      city?: string | null;
      state?: string | null;
      reference?: string | null;
      is_default?: boolean | null;
      created_at?: string | null;
      updated_at?: string | null;
    }> | null;
  };
  orders?: Array<{
    id: string;
    number: number;
    status: string;
    total_amount: number;
    created_at: string;
    share_token?: string | null;
  }>;
};

export const dynamic = "force-dynamic";
export const revalidate = 0;

export async function generateMetadata(props: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const params = await props.params;
  const slug = params.slug;
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
  const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

  if (!url || !anon) {
    return {
      title: { absolute: "Área do Cliente" },
    };
  }

  const supabase = createSupabaseClient(url, anon);
  const { data: profile } = await supabase
    .from("profiles")
    .select("catalog_name,store_name")
    .eq("slug", slug)
    .maybeSingle();

  const storeName = profile?.catalog_name || profile?.store_name || "Loja";

  return {
    title: { absolute: `Área do Cliente | ${storeName}` },
  };
}

export default async function ClientPortalPage(props: {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ portal_token?: string; section?: string; orderId?: string }>;
}) {
  const params = await props.params;
  const searchParams = await props.searchParams;
  const slug = params.slug;
  const cookieStore = await cookies();
  const cookieToken = cookieStore.get("ks_client_portal")?.value || "";
  const queryToken = String(searchParams?.portal_token || "").trim();
  const initialSection = String(searchParams?.section || "").trim() || null;
  const orderId = String(searchParams?.orderId || "").trim();
  const token = cookieToken || queryToken;

  if (queryToken) {
    redirect(
      `/api/client-portal/session/bootstrap?token=${encodeURIComponent(queryToken)}&next=${encodeURIComponent(`/${slug}/cliente`)}`
    );
  }

  if (!token || !slug) {
    redirect(`/${slug}/cliente/login`);
  }

  const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
  const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
  if (!url || !anon) {
    redirect(`/${slug}/cliente/login`);
  }

  const supabase = createSupabaseClient(url, anon);
  const { data, error } = await supabase.rpc("client_portal_get_session", {
    p_slug: slug,
    p_session_token: token,
  });

  if (error || !data?.client) {
    redirect(`/${slug}/cliente/login`);
  }

  const payload = data as SessionPayload;
  const sessionClient = payload.client as NonNullable<SessionPayload["client"]>;
  const client = applyPreferredAddressToClient(sessionClient, sessionClient.addresses || []);
  let persistedAvatarUrl = await resolveClientAvatarUrl(client?.avatar_url);
  const orders = Array.isArray(payload.orders) ? payload.orders : [];
  const storeName = payload.profile?.catalog_name || payload.profile?.store_name || "Loja";
  let orderDetails: unknown | null = null;

  if (orderId) {
    try {
      orderDetails = await getClientPortalOrderDetails({ slug, token, orderId });
    } catch {
      orderDetails = null;
    }
  }

  let favoriteProducts: FavoriteProduct[] = [];
  let reviewHistory: ReviewHistoryItem[] = [];

  try {
    if (client?.id) {
      const admin = createAdminClient();
      const { data: clientRecord } = await admin
        .from("clients")
        .select("avatar_url, favorites")
        .eq("id", client.id)
        .single();
      persistedAvatarUrl = (await resolveClientAvatarUrl(clientRecord?.avatar_url)) || persistedAvatarUrl;
      
      const favorites = clientRecord?.favorites;
      if (Array.isArray(favorites) && favorites.length > 0) {
        const { data: favProducts, error: favError } = await admin
          .from("products")
          .select("id, name, price, image_url, price_on_request, unit_type, product_price_tiers(min_qty,unit_price)")
          .in("id", favorites)
          .eq("active", true)
          .eq("show_in_catalog", true);
        
        if (favProducts) {
          /* Os favoritos respeitam a regra de preco da loja, como a vitrine. */
          const { visao } = await lerVisaoDaLoja(slug, (await carregarLoja(slug))?.profile);
          favoriteProducts = (visao.mostrarPreco ? favProducts : semPrecosNaLista(favProducts)) as FavoriteProduct[];
        } else console.error("Error fetching fav products:", favError);
      }

      const { data: reviewRows } = await admin
        .from("product_reviews")
        .select("id,product_id,rating,comment,status,created_at,updated_at")
        .eq("client_id", client.id)
        .order("created_at", { ascending: false });

      const productIds = Array.from(
        new Set(
          ((reviewRows || []) as Array<{ product_id?: string | null }>)
            .map((review) => String(review.product_id || "").trim())
            .filter(Boolean)
        )
      );

      const productsById = new Map<string, { name: string; image_url: string | null }>();
      if (productIds.length > 0) {
        const { data: productsData } = await admin
          .from("products")
          .select("id,name,image_url")
          .in("id", productIds);

        ((productsData || []) as Array<{ id: string; name?: string | null; image_url?: string | null }>).forEach((product) => {
          productsById.set(product.id, {
            name: String(product.name || "Produto").trim() || "Produto",
            image_url: product.image_url || null,
          });
        });
      }

      reviewHistory = ((reviewRows || []) as Array<{
        id: string;
        product_id: string;
        rating: number;
        comment?: string | null;
        status: "pending" | "approved" | "rejected";
        created_at: string;
        updated_at?: string | null;
      }>)
        .filter((review) => productsById.has(review.product_id))
        .map((review) => {
          const product = productsById.get(review.product_id);
          return {
            id: review.id,
            product_id: review.product_id,
            product_name: product?.name || "Produto",
            product_image_url: product?.image_url || null,
            rating: Number(review.rating || 0),
            comment: String(review.comment || "").trim(),
            status: review.status,
            created_at: review.created_at,
            updated_at: review.updated_at || null,
          };
        });
    }
  } catch (err) {
    console.error("ERROR FETCHING FAVORITES:", err);
    // Fallback silencioso para não quebrar o portal em ambientes sem service role.
  }

  const { data: profileData } = await supabase
    .from("profiles")
    .select("primary_color,catalog_logo_url,logo_url,whatsapp,company_phone,company_whatsapp,address")
    .eq("slug", slug)
    .maybeSingle();

  const primaryColor = profileData?.primary_color || "#4425A7";
  const logoUrl = profileData?.catalog_logo_url || profileData?.logo_url || "";

  return (
    <ClientPortalDashboard
      slug={slug}
      storeName={storeName}
      logoUrl={logoUrl}
      primaryColor={primaryColor}
      client={{ ...client, avatar_url: persistedAvatarUrl }}
      orders={orders}
      favoriteProducts={favoriteProducts}
      reviews={reviewHistory}
      storeEmail={payload.profile?.store_name ? "" : ""} // We don't have store email in profiles yet
      storeWhatsapp={profileData?.company_whatsapp || profileData?.whatsapp}
      storePhone={profileData?.company_phone}
      storeAddress={profileData?.address}
      initialSection={initialSection as SectionId | null}
      orderDetails={
        orderDetails && typeof orderDetails === "object" && "order" in orderDetails
          ? (orderDetails as ClientPortalOrderDetails)
          : null
      }
    />
  );
}
