"use server";

import { compare, hash } from "bcryptjs";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { z } from "zod";
import { requirePlatformAccess } from "@/lib/auth";
import { AsaasProvider } from "@/lib/billing/asaas";
import { db } from "@/lib/db";
import { normalizeSlug } from "@/lib/tenant";
import { storeMarketingMaterial } from "@/lib/storage/marketing";

async function requireSuperAdmin() {
  const {user}=await requirePlatformAccess(["SUPER_ADMIN"]);
  return user;
}

export async function resetTenantAdminPassword(formData: FormData) {
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);
  const input = z.object({
    tenantId: z.string().min(1),
    userId: z.string().min(1),
    password: z.string().min(10).max(128),
    confirmation: z.string().min(10).max(128),
  }).parse(Object.fromEntries(formData));
  if (input.password !== input.confirmation) throw new Error("As senhas não coincidem");
  const membership = await db.tenantUser.findFirst({ where: { tenantId: input.tenantId, userId: input.userId, active: true, role: "TENANT_ADMIN" } });
  if (!membership) throw new Error("Administrador da empresa não encontrado");
  await db.$transaction([
    db.user.update({ where: { id: input.userId }, data: { passwordHash: await hash(input.password, 12) } }),
    db.session.deleteMany({ where: { userId: input.userId } }),
    db.auditLog.create({ data: { tenantId: input.tenantId, actorId: actor.id, action: "tenant.admin.password_reset", entity: "User", entityId: input.userId } }),
  ]);
  revalidatePath("/admin/empresas");
  redirect("/admin/empresas?senha=alterada");
}

export async function updateTenantLocation(formData: FormData) {
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","SELLER"]);
  const input=z.object({tenantId:z.string().min(1),state:z.enum(["AC","AL","AP","AM","BA","CE","DF","ES","GO","MA","MT","MS","MG","PA","PB","PR","PE","PI","RJ","RN","RS","RO","RR","SC","SP","SE","TO"]),city:z.string().min(2).max(100)}).parse(Object.fromEntries(formData));
  await db.$transaction([db.tenant.update({where:{id:input.tenantId},data:{state:input.state,city:input.city}}),db.auditLog.create({data:{tenantId:input.tenantId,actorId:actor.id,action:"tenant.location.updated",entity:"Tenant",entityId:input.tenantId,metadata:{state:input.state,city:input.city}}})]);
  revalidatePath("/admin/empresas");
  redirect("/admin/empresas?localizacao=alterada");
}

const moneyToCents=(value:string)=>{const text=value.trim();const normalized=text.includes(",")?text.replace(/\./g,"").replace(",","."):text;const amount=Number(normalized);if(!Number.isFinite(amount)||amount<0)throw new Error("Preço inválido");return Math.round(amount*100)};
const optionalLimit=(value:FormDataEntryValue|null)=>{const text=String(value??"").trim();if(!text)return null;const parsed=Number(text);if(!Number.isInteger(parsed)||parsed<0)throw new Error("Limite inválido");return parsed};

export async function updatePlan(formData: FormData) {
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","FINANCE"]);
  const input=z.object({planId:z.string().min(1),name:z.string().min(2).max(80),price:z.string().min(1),setupFee:z.string().optional(),active:z.string().optional()}).parse(Object.fromEntries(formData));
  const plan=await db.plan.findUnique({where:{id:input.planId}});if(!plan)throw new Error("Plano não encontrado");
  const limits={products:optionalLimit(formData.get("products")),services:optionalLimit(formData.get("services")),users:optionalLimit(formData.get("users")),custom_domain:optionalLimit(formData.get("custom_domain"))};
  await db.$transaction(async tx=>{await tx.plan.update({where:{id:plan.id},data:{name:input.name,priceCents:moneyToCents(input.price),setupFeeCents:moneyToCents(input.setupFee||"290"),active:input.active==="on"}});for(const [key,limit] of Object.entries(limits)){await tx.planFeature.upsert({where:{planId_key:{planId:plan.id,key}},update:{limit,enabled:true},create:{planId:plan.id,key,limit,enabled:true}})}await tx.auditLog.create({data:{actorId:actor.id,action:"plan.updated",entity:"Plan",entityId:plan.id,metadata:{code:plan.code}}})});
  revalidatePath("/admin/planos");redirect("/admin/planos?plano=alterado");
}

export async function createPlan(formData: FormData) {
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","FINANCE"]);
  const input=z.object({code:z.string().min(2).max(30),name:z.string().min(2).max(80),price:z.string().min(1),setupFee:z.string().optional(),active:z.string().optional()}).parse(Object.fromEntries(formData));
  const code=normalizeSlug(input.code).replace(/-/g,"_").toUpperCase();
  if(!/^[A-Z0-9_]+$/.test(code))throw new Error("Código do plano inválido");
  const existing=await db.plan.findUnique({where:{code},select:{id:true}});
  if(existing)redirect("/admin/planos?erro=codigo-existente");
  const limits={products:optionalLimit(formData.get("products")),services:optionalLimit(formData.get("services")),users:optionalLimit(formData.get("users")),custom_domain:optionalLimit(formData.get("custom_domain"))};
  await db.$transaction(async tx=>{const plan=await tx.plan.create({data:{code,name:input.name,priceCents:moneyToCents(input.price),setupFeeCents:moneyToCents(input.setupFee||"290"),active:input.active==="on"}});for(const [key,limit] of Object.entries(limits)){await tx.planFeature.create({data:{planId:plan.id,key,limit,enabled:true}})}await tx.auditLog.create({data:{actorId:actor.id,action:"plan.created",entity:"Plan",entityId:plan.id,metadata:{code}}})});
  revalidatePath("/admin/planos");redirect("/admin/planos?plano=criado");
}

const commissionToBps=(value:string)=>{const amount=Number(value.replace(",","."));if(!Number.isFinite(amount)||amount<0||amount>100)throw new Error("Comissão deve estar entre 0% e 100%");return Math.round(amount*100)};

export async function createSeller(formData:FormData){
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);
  const input=z.object({name:z.string().min(3).max(120),email:z.email(),phone:z.string().max(30).optional(),password:z.string().min(10).max(128),commission:z.string().min(1),managerId:z.string().optional()}).parse(Object.fromEntries(formData));
  const manager=input.managerId?await db.user.findFirst({where:{id:input.managerId,deletedAt:null,platformRole:{in:["ADMIN","SELLER"]}}}):null;if(input.managerId&&!manager)throw new Error("Responsável superior inválido");
  const created=await db.user.create({data:{name:input.name,email:input.email.toLowerCase(),phone:input.phone||null,passwordHash:await hash(input.password,12),platformRole:"SELLER",commissionBps:commissionToBps(input.commission),managerId:manager?.id}});
  await db.auditLog.create({data:{actorId:actor.id,action:"seller.created",entity:"User",entityId:created.id,metadata:{commissionBps:created.commissionBps,managerId:created.managerId}}});revalidatePath("/admin/vendedores");redirect("/admin/vendedores?vendedor=criado");
}

export async function updateSeller(formData:FormData){
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);
  const input=z.object({userId:z.string().min(1),name:z.string().min(3).max(120),email:z.email(),phone:z.string().max(30).optional(),commission:z.string().min(1),managerId:z.string().optional(),active:z.enum(["true","false"])}).parse(Object.fromEntries(formData));
  const target=await db.user.findFirst({where:{id:input.userId,platformRole:"SELLER"}});if(!target)throw new Error("Vendedor não encontrado");if(input.managerId===target.id)throw new Error("Um vendedor não pode responder a si mesmo");
  const manager=input.managerId?await db.user.findFirst({where:{id:input.managerId,deletedAt:null,platformRole:{in:["ADMIN","SELLER"]}}}):null;if(input.managerId&&!manager)throw new Error("Responsável superior inválido");
  let cursor=manager;while(cursor?.managerId){if(cursor.managerId===target.id)throw new Error("Essa alteração criaria um ciclo na hierarquia");cursor=await db.user.findUnique({where:{id:cursor.managerId}})}
  await db.$transaction([db.user.update({where:{id:target.id},data:{name:input.name,email:input.email.toLowerCase(),phone:input.phone||null,commissionBps:commissionToBps(input.commission),managerId:manager?.id??null,deletedAt:input.active==="true"?null:new Date()}}),db.auditLog.create({data:{actorId:actor.id,action:"seller.updated",entity:"User",entityId:target.id,metadata:{managerId:manager?.id??null,active:input.active}}})]);revalidatePath("/admin/vendedores");redirect("/admin/vendedores?vendedor=alterado");
}

export async function updateOwnPlatformProfile(formData:FormData){
  const {user}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","FINANCE","SELLER"]);const input=z.object({name:z.string().min(3).max(120),email:z.email(),phone:z.string().max(30).optional()}).parse(Object.fromEntries(formData));await db.user.update({where:{id:user.id},data:{name:input.name,email:input.email.toLowerCase(),phone:input.phone||null}});await db.auditLog.create({data:{actorId:user.id,action:"platform.profile.updated",entity:"User",entityId:user.id}});revalidatePath("/admin/configuracoes");redirect("/admin/configuracoes?perfil=alterado");
}

export async function changeOwnPlatformPassword(formData:FormData){
  const {user}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","FINANCE","SELLER"]);const input=z.object({currentPassword:z.string().min(1),password:z.string().min(10).max(128),confirmation:z.string().min(10).max(128)}).parse(Object.fromEntries(formData));if(input.password!==input.confirmation)throw new Error("As novas senhas não coincidem");const saved=await db.user.findUniqueOrThrow({where:{id:user.id},select:{passwordHash:true}});if(!(await compare(input.currentPassword,saved.passwordHash)))throw new Error("Senha atual incorreta");await db.$transaction([db.user.update({where:{id:user.id},data:{passwordHash:await hash(input.password,12)}}),db.session.deleteMany({where:{userId:user.id}}),db.auditLog.create({data:{actorId:user.id,action:"platform.password.changed",entity:"User",entityId:user.id}})]);redirect("/admin/login");
}

export async function createPlatformUser(formData:FormData){const actor=await requireSuperAdmin();const input=z.object({name:z.string().min(3).max(120),email:z.email(),password:z.string().min(10).max(128),role:z.enum(["ADMIN","FINANCE","SELLER"])}).parse(Object.fromEntries(formData));const created=await db.user.create({data:{name:input.name,email:input.email.toLowerCase(),passwordHash:await hash(input.password,12),platformRole:input.role}});await db.auditLog.create({data:{actorId:actor.id,action:"platform.user.created",entity:"User",entityId:created.id,metadata:{role:input.role}}});revalidatePath("/admin/equipe");redirect("/admin/equipe?usuario=criado")}

export async function updatePlatformUser(formData:FormData){const actor=await requireSuperAdmin();const input=z.object({userId:z.string(),role:z.enum(["ADMIN","FINANCE","SELLER"]),active:z.enum(["true","false"])}).parse(Object.fromEntries(formData));const target=await db.user.findUnique({where:{id:input.userId}});if(!target||target.isSuperAdmin)throw new Error("Usuário protegido");await db.$transaction([db.user.update({where:{id:target.id},data:{platformRole:input.role,deletedAt:input.active==="true"?null:new Date()}}),db.session.deleteMany({where:{userId:target.id}}),db.auditLog.create({data:{actorId:actor.id,action:"platform.user.updated",entity:"User",entityId:target.id,metadata:{role:input.role,active:input.active}}})]);revalidatePath("/admin/equipe")}

export async function createTenantByStaff(formData:FormData){const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","SELLER"]);const input=z.object({responsible:z.string().min(3).max(120),company:z.string().min(2).max(120),document:z.string().min(11).max(18),email:z.email(),password:z.string().min(10).max(128),phone:z.string().min(8).max(30),whatsapp:z.string().max(30).optional(),city:z.string().min(2).max(100),state:z.string().length(2),segment:z.string().min(2).max(80),subdomain:z.string().min(3).max(63),businessModel:z.enum(["PRODUCTS","SERVICES","MIXED"]),planId:z.string()}).parse(Object.fromEntries(formData));const plan=await db.plan.findFirst({where:{id:input.planId,active:true}});if(!plan)throw new Error("Plano inválido");const slug=normalizeSlug(input.subdomain);await db.$transaction(async tx=>{const user=await tx.user.create({data:{name:input.responsible,email:input.email.toLowerCase(),passwordHash:await hash(input.password,12)}});const tenant=await tx.tenant.create({data:{name:input.company,legalDocument:input.document.replace(/\D/g,""),slug,email:input.email.toLowerCase(),phone:input.phone,whatsapp:input.whatsapp||null,city:input.city,state:input.state,segment:input.segment,businessModel:input.businessModel}});await tx.tenantUser.create({data:{tenantId:tenant.id,userId:user.id,role:"TENANT_ADMIN"}});await tx.domain.create({data:{tenantId:tenant.id,hostname:`${slug}.${process.env.ROOT_DOMAIN??"localhost:3000"}`,primary:true,status:"VERIFIED",verifiedAt:new Date()}});await tx.themeSetting.create({data:{tenantId:tenant.id}});await tx.subscription.create({data:{tenantId:tenant.id,planId:plan.id,priceCents:plan.priceCents,trialEndsAt:new Date(Date.now()+14*86400000)}});await tx.auditLog.create({data:{tenantId:tenant.id,actorId:actor.id,action:"tenant.created_by_staff",entity:"Tenant",entityId:tenant.id}})});revalidatePath("/admin/empresas");redirect("/admin/empresas?empresa=criada")}

export async function createManualCampaignLead(formData:FormData){
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","SELLER"]);
  const input=z.object({responsibleName:z.string().min(3).max(120),companyName:z.string().min(2).max(120),document:z.string().min(11).max(18),email:z.email(),phone:z.string().min(8).max(30),city:z.string().min(2).max(100),state:z.string().length(2),segment:z.string().min(2).max(80),businessModel:z.enum(["PRODUCTS","SERVICES","MIXED"]),planId:z.string().min(1),sellerId:z.string().optional(),domain:z.string().max(120).optional(),setupFee:z.string().min(1),createBilling:z.string().optional()}).parse(Object.fromEntries(formData));
  const plan=await db.plan.findFirst({where:{id:input.planId,active:true}});
  if(!plan)throw new Error("Plano indisponível");
  const seller=input.sellerId?await db.user.findFirst({where:{id:input.sellerId,platformRole:"SELLER",deletedAt:null},select:{id:true}}):null;
  if(input.sellerId&&!seller)throw new Error("Vendedor inválido");
  const moduleIds=formData.getAll("modules").map(String);
  const modules=await db.addonModule.findMany({where:{id:{in:moduleIds},active:true,future:false}});
  if(modules.length!==new Set(moduleIds).size)throw new Error("Um dos módulos selecionados está indisponível");
  const setupFeeCents=moneyToCents(input.setupFee);
  const monthlyCents=plan.priceCents+modules.reduce((sum,item)=>sum+item.priceCents,0);
  if(input.createBilling==="on"&&setupFeeCents<=0)throw new Error("Informe uma taxa de adesão maior que zero para gerar a cobrança");
  const lead=await db.campaignLead.create({data:{responsibleName:input.responsibleName,companyName:input.companyName,document:input.document.replace(/\D/g,""),email:input.email.toLowerCase(),phone:input.phone,city:input.city,state:input.state.toUpperCase(),segment:input.segment,businessModel:input.businessModel,domain:input.domain?.trim().toLowerCase()||null,domainMode:input.domain?"EXISTING":"NEW",planId:plan.id,planName:plan.name,monthlyCents,setupFeeCents,selectedModules:modules.map(item=>({id:item.id,name:item.name,priceCents:item.priceCents})),sellerId:seller?.id??(actor.platformRole==="SELLER"?actor.id:null),status:"NEW",publicationStatus:"MANUAL_CONTACT"}});
  await db.auditLog.create({data:{actorId:actor.id,action:"lead.created_by_staff",entity:"CampaignLead",entityId:lead.id,metadata:{companyName:lead.companyName}}});
  if(input.createBilling==="on"){
    try{
      const provider=new AsaasProvider();
      const customer=await provider.createCustomer({tenantId:lead.id,name:lead.companyName,document:lead.document,email:lead.email,phone:lead.phone});
      const payment=await provider.createPayment({leadId:lead.id,customerId:customer.id,valueCents:setupFeeCents,dueDate:new Date(Date.now()+3*86400000),description:`Taxa de adesão Inixis — ${plan.name} — atendimento manual`});
      const subscriptionStartsAt=new Date(Date.now()+30*86400000);
      const subscription=await provider.createSubscription({localSubscriptionId:`campaign-${lead.id}`,customerId:customer.id,billingType:"UNDEFINED",valueCents:monthlyCents,nextDueDate:subscriptionStartsAt,description:`Mensalidade Inixis — ${plan.name}${modules.length?` + ${modules.map(item=>item.name).join(", ")}`:""}`});
      await db.campaignLead.update({where:{id:lead.id},data:{paymentUrl:payment.invoiceUrl||payment.bankSlipUrl||null,paymentExternalId:payment.id,subscriptionExternalId:subscription.id,subscriptionStartsAt,status:"AWAITING_PAYMENT",publicationStatus:"PENDING_PAYMENT"}});
    }catch(error){
      console.error("manual_lead_billing_failed",error);
      await db.campaignLead.update({where:{id:lead.id},data:{status:"BILLING_ERROR"}});
      revalidatePath("/admin/leads");
      redirect("/admin/leads?lead=cobranca-erro");
    }
  }
  revalidatePath("/admin/leads");
  redirect(`/admin/leads?lead=${input.createBilling==="on"?"cobranca-criada":"criado"}`);
}

export async function activateCampaignLead(formData:FormData){
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","SELLER"]);
  const input=z.object({leadId:z.string().min(1),subdomain:z.string().min(3).max(63),password:z.string().min(10).max(128)}).parse(Object.fromEntries(formData));
  const lead=await db.campaignLead.findUnique({where:{id:input.leadId}});
  if(!lead)throw new Error("Lead não encontrado");
  if(lead.status==="CONVERTED")throw new Error("Este lead já foi ativado");
  const plan=await db.plan.findUnique({where:{id:lead.planId}});
  if(!plan)throw new Error("Plano do lead não encontrado");
  const slug=normalizeSlug(input.subdomain);
  if(slug.length<3)throw new Error("Subdomínio inválido");
  const document=lead.document.replace(/\D/g,"");
  const email=lead.email.toLowerCase();
  const duplicate=await db.tenant.findFirst({where:{OR:[{legalDocument:document},{slug},{users:{some:{user:{email}}}}]},select:{id:true}});
  if(duplicate)throw new Error("Já existe uma empresa com este documento, e-mail ou subdomínio");
  const passwordHash=await hash(input.password,12);
  await db.$transaction(async tx=>{
    const user=await tx.user.create({data:{name:lead.responsibleName,email,passwordHash,phone:lead.phone}});
    const tenant=await tx.tenant.create({data:{name:lead.companyName,legalDocument:document,slug,email,phone:lead.phone,whatsapp:lead.phone,city:lead.city,state:lead.state,segment:lead.segment,businessModel:lead.businessModel,status:"ACTIVE"}});
    await tx.tenantUser.create({data:{tenantId:tenant.id,userId:user.id,role:"TENANT_ADMIN"}});
    await tx.domain.create({data:{tenantId:tenant.id,hostname:`${slug}.${process.env.ROOT_DOMAIN??"localhost:3000"}`,primary:true,status:"VERIFIED",verifiedAt:new Date()}});
    await tx.themeSetting.create({data:{tenantId:tenant.id,logoUrl:lead.logoUrl}});
    await tx.subscription.create({data:{tenantId:tenant.id,planId:plan.id,status:"ACTIVE",priceCents:lead.monthlyCents,provider:lead.subscriptionExternalId?"ASAAS":undefined,externalSubscriptionId:lead.subscriptionExternalId,billingType:lead.subscriptionExternalId?"UNDEFINED":null,startedAt:new Date()}});
    await tx.campaignLead.update({where:{id:lead.id},data:{status:"CONVERTED",publicationStatus:"ACTIVE"}});
    await tx.auditLog.create({data:{tenantId:tenant.id,actorId:actor.id,action:"lead.converted_to_tenant",entity:"CampaignLead",entityId:lead.id,metadata:{tenantId:tenant.id,slug}}});
  });
  revalidatePath("/admin/leads");
  revalidatePath("/admin/empresas");
  redirect("/admin/leads?lead=ativado");
}

export async function updateTenantDetails(formData:FormData){const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","SELLER"]);const input=z.object({tenantId:z.string(),name:z.string().min(2).max(120),document:z.string().min(11).max(18),email:z.email(),phone:z.string().min(8).max(30),whatsapp:z.string().max(30).optional(),segment:z.string().min(2).max(80),businessModel:z.enum(["PRODUCTS","SERVICES","MIXED"]),status:z.enum(["TRIAL","ACTIVE","SUSPENDED","CANCELLED"])}).parse(Object.fromEntries(formData));await db.$transaction([db.tenant.update({where:{id:input.tenantId},data:{name:input.name,legalDocument:input.document.replace(/\D/g,""),email:input.email.toLowerCase(),phone:input.phone,whatsapp:input.whatsapp||null,segment:input.segment,businessModel:input.businessModel,status:input.status}}),db.auditLog.create({data:{tenantId:input.tenantId,actorId:actor.id,action:"tenant.details.updated",entity:"Tenant",entityId:input.tenantId}})]);revalidatePath("/admin/empresas");redirect("/admin/empresas?empresa=alterada")}

const blogInput=z.object({postId:z.string().optional(),title:z.string().min(5).max(160),slug:z.string().max(180).optional(),excerpt:z.string().min(20).max(320),content:z.string().min(80).max(50000),category:z.string().min(2).max(80),coverImageUrl:z.string().url().optional().or(z.literal("")),seoTitle:z.string().max(65).optional(),metaDescription:z.string().max(160).optional(),published:z.string().optional()});
export async function saveBlogPost(formData:FormData){const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);const input=blogInput.parse(Object.fromEntries(formData));const slug=normalizeSlug(input.slug||input.title);const published=input.published==="on";const data={title:input.title,slug,excerpt:input.excerpt,content:input.content,category:input.category,coverImageUrl:input.coverImageUrl||null,seoTitle:input.seoTitle||input.title.slice(0,65),metaDescription:input.metaDescription||input.excerpt.slice(0,160),published,publishedAt:published?new Date():null};const post=input.postId?await db.blogPost.update({where:{id:input.postId},data}):await db.blogPost.create({data:{...data,authorId:actor.id}});await db.auditLog.create({data:{actorId:actor.id,action:input.postId?"blog.post.updated":"blog.post.created",entity:"BlogPost",entityId:post.id,metadata:{slug,published}}});revalidatePath("/admin/blog");redirect("/admin/blog?salvo=1")}
export async function deleteBlogPost(formData:FormData){const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);const id=z.string().min(1).parse(formData.get("postId"));const post=await db.blogPost.delete({where:{id}});await db.auditLog.create({data:{actorId:actor.id,action:"blog.post.deleted",entity:"BlogPost",entityId:id,metadata:{slug:post.slug}}});revalidatePath("/admin/blog");redirect("/admin/blog?excluido=1")}

export async function saveAddonModule(formData:FormData){const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN","FINANCE"]);const input=z.object({name:z.string().min(2).max(80),code:z.string().min(2).max(40),description:z.string().min(5).max(240),price:z.string().min(1),setupFee:z.string().optional(),active:z.string().optional(),future:z.string().optional()}).parse(Object.fromEntries(formData));const code=normalizeSlug(input.code).replace(/-/g,"_").toUpperCase();const addon=await db.addonModule.upsert({where:{code},update:{name:input.name,description:input.description,priceCents:moneyToCents(input.price),active:input.active==="on",future:input.future==="on"},create:{code,name:input.name,description:input.description,priceCents:moneyToCents(input.price),active:input.active==="on",future:input.future==="on"}});await db.auditLog.create({data:{actorId:actor.id,action:"addon.saved",entity:"AddonModule",entityId:addon.id}});revalidatePath("/admin/planos");redirect("/admin/planos?modulo=salvo")}

export async function createMarketingPackage(formData:FormData){
  const {user:actor}=await requirePlatformAccess(["SUPER_ADMIN","ADMIN"]);
  const input=z.object({title:z.string().min(3).max(120),category:z.string().min(2).max(80),description:z.string().min(10).max(500),salesScript:z.string().min(20).max(10000),active:z.string().optional()}).parse(Object.fromEntries(formData));
  const files=formData.getAll("materials").filter((item):item is File=>item instanceof File&&item.size>0);
  if(files.length>5)throw new Error("Cada pacote aceita no máximo cinco arquivos");
  const saved=[];
  for(const file of files)saved.push({file,stored:await storeMarketingMaterial(file)});
  const created=await db.marketingPackage.create({data:{title:input.title,category:input.category,description:input.description,salesScript:input.salesScript,active:input.active==="on",materials:{create:saved.map(({file,stored},index)=>({title:file.name,fileUrl:stored.url,storageKey:stored.storageKey,mimeType:stored.mimeType,sizeBytes:stored.sizeBytes,sortOrder:index}))}}});
  await db.auditLog.create({data:{actorId:actor.id,action:"marketing.package.created",entity:"MarketingPackage",entityId:created.id,metadata:{files:files.length,category:input.category}}});
  revalidatePath("/admin/marketing");
  redirect("/admin/marketing?pacote=criado");
}
