import type { SupabaseClient, User } from "@supabase/supabase-js";
import { canCompany, getCompanyContext } from "@/lib/company-context";
import { ApiV1Error } from "@/lib/api-v1/errors";
import { avisarLoja } from "@/lib/loja/avisar-loja";

function getProfileTargetId(ctx: Awaited<ReturnType<typeof getCompanyContext>>, user: User) {
  return ctx.ownerId || user.id;
}

export async function getCompanyProfile(params: { supabase: SupabaseClient; user: User }) {
  const ctx = await getCompanyContext(params.supabase, params.user);
  const profileId = getProfileTargetId(ctx, params.user);

  const [{ data: profile, error: profileError }, { data: company, error: companyError }] = await Promise.all([
    params.supabase
      .from("profiles")
      .select(
        "id,store_name,logo_url,cnpj,phone,company_whatsapp,address_zip,address_street,address_number,address_complement,address_neighborhood,address_city,address_state,address"
      )
      .eq("id", profileId)
      .maybeSingle(),
    params.supabase.from("companies").select("id,name,owner_id").eq("id", ctx.companyId).maybeSingle(),
  ]);

  if (profileError) throw new ApiV1Error(400, "company_profile_fetch_failed", profileError.message);
  if (companyError) throw new ApiV1Error(400, "company_fetch_failed", companyError.message);

  return {
    ok: true,
    data: {
      id: ctx.companyId,
      profile_id: profileId,
      name: (company as any)?.name || (profile as any)?.store_name || null,
      owner_id: (company as any)?.owner_id || ctx.ownerId || null,
      store_name: (profile as any)?.store_name || "",
      logo_url: (profile as any)?.logo_url || "",
      cnpj: (profile as any)?.cnpj || "",
      phone: (profile as any)?.phone || "",
      company_whatsapp: (profile as any)?.company_whatsapp || "",
      address_zip: (profile as any)?.address_zip || "",
      address_street: (profile as any)?.address_street || "",
      address_number: (profile as any)?.address_number || "",
      address_complement: (profile as any)?.address_complement || "",
      address_neighborhood: (profile as any)?.address_neighborhood || "",
      address_city: (profile as any)?.address_city || "",
      address_state: (profile as any)?.address_state || "",
      address: (profile as any)?.address || "",
    },
  };
}

export async function updateCompanyProfile(params: {
  supabase: SupabaseClient;
  user: User;
  body: Record<string, unknown> | null;
}) {
  const ctx = await getCompanyContext(params.supabase, params.user);
  if (!canCompany(ctx, params.user.id, "company.data.write")) {
    throw new ApiV1Error(403, "forbidden", "Sem permissao para editar a empresa.");
  }

  const profileId = getProfileTargetId(ctx, params.user);
  const body = params.body || {};
  const updates = {
    id: profileId,
    logo_url: typeof body.logo_url === "string" ? body.logo_url : "",
    store_name: typeof body.store_name === "string" ? body.store_name : "",
    cnpj: typeof body.cnpj === "string" ? body.cnpj : "",
    phone: typeof body.phone === "string" ? body.phone : "",
    company_whatsapp: typeof body.company_whatsapp === "string" ? body.company_whatsapp : "",
    address_zip: typeof body.address_zip === "string" ? body.address_zip : "",
    address_street: typeof body.address_street === "string" ? body.address_street : "",
    address_number: typeof body.address_number === "string" ? body.address_number : "",
    address_complement: typeof body.address_complement === "string" ? body.address_complement : "",
    address_neighborhood: typeof body.address_neighborhood === "string" ? body.address_neighborhood : "",
    address_city: typeof body.address_city === "string" ? body.address_city : "",
    address_state: typeof body.address_state === "string" ? body.address_state : "",
    address: typeof body.address === "string" ? body.address : "",
    updated_at: new Date().toISOString(),
  };

  const { error } = await params.supabase.from("profiles").upsert(updates);
  if (error) throw new ApiV1Error(400, "company_profile_update_failed", error.message);

  /* Nome, logo, telefone e endereço aparecem na loja, que guarda o perfil por
     dois minutos. */
  avisarLoja(profileId);

  return getCompanyProfile({
    supabase: params.supabase,
    user: params.user,
  });
}
