import { Router, Request, Response, NextFunction } from "express";
import { compassStorage } from "./storage";
import { crmStorage } from "../crm/storage";
import { productionStorage } from "../production/storage";
import { valuationStorage } from "../valuation/storage";
import { 
  insertTenantSchema, insertTenantUserSchema,
  insertPcClientSchema, insertPcClientContactSchema,
  insertPcProjectSchema, insertPcProjectMemberSchema,
  insertPcCanvasBlockSchema, insertPcCanvasQuestionSchema, insertPcCanvasExpectedOutputSchema,
  insertPcCanvasPdcaLinkSchema, insertPcCanvasSwotLinkSchema,
  insertPcProcessSchema, insertPcProcessStepSchema,
  insertPcSwotAnalysisSchema, insertPcSwotItemSchema, updatePcSwotItemSchema,
  insertPcCrmStageSchema, insertPcCrmLeadSchema, insertPcCrmOpportunitySchema, insertPcCrmActivitySchema,
  insertPcDeliverableSchema, insertPcTaskSchema,
  insertPcPdcaCycleSchema, insertPcPdcaActionSchema, insertPcRequirementSchema,
  insertPcReportTemplateSchema, insertPcReportConfigurationSchema, insertPcGeneratedReportSchema,
  insertPcErpModuleSchema, insertPcErpRequirementSchema, insertPcErpParameterizationTopicSchema, insertPcErpParameterizationItemSchema
} from "@shared/schema";

const router = Router();

// Authentication middleware
function requireAuth(req: Request, res: Response, next: NextFunction) {
  if (!req.isAuthenticated() || !req.user) {
    return res.status(401).json({ error: "Não autorizado" });
  }
  next();
}

// Apply auth to all routes
router.use(requireAuth);

// Helper to get tenant ID from request header or user's first tenant
async function getTenantId(req: Request): Promise<number | null> {
  const userId = (req.user as any).id;
  const headerTenantId = req.headers["x-tenant-id"];
  if (headerTenantId) {
    const tenantId = parseInt(headerTenantId as string);
    const isMember = await compassStorage.isUserInTenant(userId, tenantId);
    return isMember ? tenantId : null;
  }
  const tenants = await compassStorage.getUserTenants(userId);
  return tenants.length > 0 ? tenants[0].id : null;
}

// Validate tenant membership
async function validateTenantMembership(userId: string, tenantId: number): Promise<boolean> {
  return await compassStorage.isUserInTenant(userId, tenantId);
}

// Helper to validate project belongs to tenant
async function validateProjectAccess(projectId: number, tenantId: number): Promise<boolean> {
  const project = await compassStorage.getProject(projectId, tenantId);
  return !!project;
}

// Helper to validate client exists (agora usando CRM centralizado)
async function validateClientAccess(clientId: number): Promise<boolean> {
  const client = await crmStorage.getClient(clientId);
  return !!client;
}

// ========== TENANTS ==========
router.get("/tenants", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenants = await compassStorage.getUserTenants(userId);
    res.json(tenants);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/tenants/:id", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = parseInt(req.params.id);
    const isMember = await validateTenantMembership(userId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const tenant = await compassStorage.getTenant(tenantId);
    if (!tenant) return res.status(404).json({ error: "Tenant não encontrado" });
    res.json(tenant);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/tenants", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const parsed = insertTenantSchema.parse(req.body);
    const tenant = await compassStorage.createTenant(parsed);
    await compassStorage.addUserToTenant({ tenantId: tenant.id, userId, role: "owner", isOwner: "true" });
    res.status(201).json(tenant);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/tenants/:id", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = parseInt(req.params.id);
    const isMember = await validateTenantMembership(userId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const tenant = await compassStorage.updateTenant(tenantId, req.body);
    if (!tenant) return res.status(404).json({ error: "Tenant não encontrado" });
    res.json(tenant);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/tenants/:id", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = parseInt(req.params.id);
    const isMember = await validateTenantMembership(userId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const deleted = await compassStorage.deleteTenant(tenantId);
    if (!deleted) return res.status(404).json({ error: "Tenant não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== TENANT USERS ==========
router.get("/tenants/:tenantId/users", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = parseInt(req.params.tenantId);
    const isMember = await validateTenantMembership(userId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const users = await compassStorage.getTenantUsers(tenantId);
    res.json(users);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/tenants/:tenantId/users", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = parseInt(req.params.tenantId);
    const isMember = await validateTenantMembership(userId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const parsed = insertTenantUserSchema.parse({ ...req.body, tenantId });
    const tu = await compassStorage.addUserToTenant(parsed);
    res.status(201).json(tu);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/tenants/:tenantId/users/:userId", async (req: Request, res: Response) => {
  try {
    const currentUserId = (req.user as any).id;
    const tenantId = parseInt(req.params.tenantId);
    const isMember = await validateTenantMembership(currentUserId, tenantId);
    if (!isMember) return res.status(403).json({ error: "Acesso negado ao tenant" });
    const deleted = await compassStorage.removeUserFromTenant(tenantId, req.params.userId);
    if (!deleted) return res.status(404).json({ error: "Usuário não encontrado no tenant" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CLIENTS (usando CRM centralizado) ==========
router.get("/clients", async (req: Request, res: Response) => {
  try {
    const clients = await crmStorage.getClients();
    res.json(clients);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/clients/:id", async (req: Request, res: Response) => {
  try {
    const client = await crmStorage.getClient(parseInt(req.params.id));
    if (!client) return res.status(404).json({ error: "Cliente não encontrado" });
    res.json(client);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CLIENT CONTACTS (deprecated - contatos agora são do CRM) ==========
router.get("/clients/:clientId/contacts", async (req: Request, res: Response) => {
  try {
    const clientId = parseInt(req.params.clientId);
    const client = await crmStorage.getClient(clientId);
    if (!client) return res.status(404).json({ error: "Cliente não encontrado" });
    res.json([]);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.delete("/contacts/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteClientContact(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Contato não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROJECTS ==========
router.get("/projects", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const clientId = req.query.clientId ? parseInt(req.query.clientId as string) : undefined;
    const projects = clientId 
      ? await compassStorage.getProjectsByClient(clientId, tenantId)
      : await compassStorage.getProjects(tenantId);
    res.json(projects);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/projects/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const project = await compassStorage.getProject(parseInt(req.params.id), tenantId);
    if (!project) return res.status(404).json({ error: "Projeto não encontrado" });
    res.json(project);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const parsed = insertPcProjectSchema.parse({ ...req.body, userId, tenantId });
    const project = await compassStorage.createProject(parsed);
    
    // Se for projeto de valuation, criar também na tabela valuation_projects
    if (parsed.projectType === "valuation") {
      try {
        // Buscar dados do cliente para preencher informações do valuation project
        const client = parsed.clientId ? await crmStorage.getClient(parsed.clientId) : null;
        await valuationStorage.createProject({
          tenantId,
          companyName: client?.name || parsed.name,
          cnpj: client?.cnpj || null,
          sector: client?.segment || "Serviços",
          businessModel: null,
          stage: "Growth",
          size: "Média",
          status: "draft",
          consultantId: userId,
          clientId: parsed.clientId || null,
        });
      } catch (syncError) {
        console.error("Erro ao sincronizar com valuation_projects:", syncError);
      }
    }
    
    res.status(201).json(project);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/projects/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const project = await compassStorage.updateProject(parseInt(req.params.id), tenantId, req.body);
    if (!project) return res.status(404).json({ error: "Projeto não encontrado" });
    res.json(project);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/projects/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const deleted = await compassStorage.deleteProject(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Projeto não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROJECT MEMBERS ==========
router.get("/projects/:projectId/members", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const members = await compassStorage.getProjectMembers(projectId);
    res.json(members);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/members", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcProjectMemberSchema.parse({ ...req.body, projectId });
    const member = await compassStorage.addProjectMember(parsed);
    res.status(201).json(member);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/project-members/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.removeProjectMember(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Membro não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CANVAS BLOCKS ==========
router.get("/projects/:projectId/canvas", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const blocks = await compassStorage.getCanvasBlocks(projectId);
    
    // Add question counts to each block
    const blocksWithStats = await Promise.all(blocks.map(async (block) => {
      const questions = await compassStorage.getCanvasQuestions(block.id);
      const answeredCount = questions.filter(q => q.score !== null && q.score > 0).length;
      return {
        ...block,
        questionsCount: questions.length,
        answeredCount: answeredCount,
      };
    }));
    
    res.json(blocksWithStats);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/canvas", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcCanvasBlockSchema.parse({ ...req.body, projectId });
    const block = await compassStorage.createCanvasBlock(parsed);
    res.status(201).json(block);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/canvas/:id", async (req: Request, res: Response) => {
  try {
    const block = await compassStorage.updateCanvasBlock(parseInt(req.params.id), req.body);
    if (!block) return res.status(404).json({ error: "Bloco não encontrado" });
    res.json(block);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/canvas/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteCanvasBlock(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Bloco não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CANVAS DIAGNOSTIC QUESTIONS ==========
router.get("/canvas/:blockId/questions", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const questions = await compassStorage.getCanvasQuestions(blockId);
    res.json(questions);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/canvas/:blockId/questions", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const parsed = insertPcCanvasQuestionSchema.parse({ ...req.body, blockId });
    const question = await compassStorage.createCanvasQuestion(parsed);
    res.status(201).json(question);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/canvas/questions/:id", async (req: Request, res: Response) => {
  try {
    const question = await compassStorage.updateCanvasQuestion(parseInt(req.params.id), req.body);
    if (!question) return res.status(404).json({ error: "Pergunta não encontrada" });
    res.json(question);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/canvas/questions/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteCanvasQuestion(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Pergunta não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CANVAS EXPECTED OUTPUTS ==========
router.get("/canvas/:blockId/outputs", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const outputs = await compassStorage.getCanvasExpectedOutputs(blockId);
    res.json(outputs);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/canvas/:blockId/outputs", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const parsed = insertPcCanvasExpectedOutputSchema.parse({ ...req.body, blockId });
    const output = await compassStorage.createCanvasExpectedOutput(parsed);
    res.status(201).json(output);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/canvas/outputs/:id", async (req: Request, res: Response) => {
  try {
    const output = await compassStorage.updateCanvasExpectedOutput(parseInt(req.params.id), req.body);
    if (!output) return res.status(404).json({ error: "Saída não encontrada" });
    res.json(output);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/canvas/outputs/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteCanvasExpectedOutput(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Saída não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CANVAS PDCA LINKS ==========
router.get("/canvas/:blockId/pdca", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const links = await compassStorage.getCanvasPdcaLinks(blockId);
    res.json(links);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/canvas/:blockId/pdca", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const parsed = insertPcCanvasPdcaLinkSchema.parse({ ...req.body, blockId });
    const link = await compassStorage.createCanvasPdcaLink(parsed);
    res.status(201).json(link);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/canvas/pdca/:id", async (req: Request, res: Response) => {
  try {
    const link = await compassStorage.updateCanvasPdcaLink(parseInt(req.params.id), req.body);
    if (!link) return res.status(404).json({ error: "Item PDCA não encontrado" });
    res.json(link);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/canvas/pdca/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteCanvasPdcaLink(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Item PDCA não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CANVAS SWOT LINKS ==========
router.get("/canvas/:blockId/swot", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const links = await compassStorage.getCanvasSwotLinks(blockId);
    res.json(links);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/canvas/:blockId/swot", async (req: Request, res: Response) => {
  try {
    const blockId = parseInt(req.params.blockId);
    const parsed = insertPcCanvasSwotLinkSchema.parse({ ...req.body, blockId });
    const link = await compassStorage.createCanvasSwotLink(parsed);
    res.status(201).json(link);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/canvas/swot/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteCanvasSwotLink(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Item SWOT não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROCESSES ==========
router.get("/projects/:projectId/processes", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const processes = await compassStorage.getProcesses(projectId);
    res.json(processes);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/processes", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcProcessSchema.parse({ ...req.body, projectId });
    const process = await compassStorage.createProcess(parsed);
    res.status(201).json(process);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/processes/:id", async (req: Request, res: Response) => {
  try {
    const process = await compassStorage.updateProcess(parseInt(req.params.id), req.body);
    if (!process) return res.status(404).json({ error: "Processo não encontrado" });
    res.json(process);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/processes/:id/diagram", async (req: Request, res: Response) => {
  try {
    const { diagramNodes, diagramEdges, diagramViewport } = req.body;
    const process = await compassStorage.updateProcess(parseInt(req.params.id), {
      diagramNodes,
      diagramEdges,
      diagramViewport,
    });
    if (!process) return res.status(404).json({ error: "Processo não encontrado" });
    res.json(process);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/processes/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteProcess(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Processo não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROCESS STEPS ==========
router.get("/processes/:processId/steps", async (req: Request, res: Response) => {
  try {
    const steps = await compassStorage.getProcessSteps(parseInt(req.params.processId));
    res.json(steps);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/processes/:processId/steps", async (req: Request, res: Response) => {
  try {
    const parsed = insertPcProcessStepSchema.parse({ ...req.body, processId: parseInt(req.params.processId) });
    const step = await compassStorage.createProcessStep(parsed);
    res.status(201).json(step);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/process-steps/:id", async (req: Request, res: Response) => {
  try {
    const step = await compassStorage.updateProcessStep(parseInt(req.params.id), req.body);
    if (!step) return res.status(404).json({ error: "Etapa não encontrada" });
    res.json(step);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/process-steps/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteProcessStep(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Etapa não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== SWOT ANALYSES ==========
router.get("/projects/:projectId/swot", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const analyses = await compassStorage.getSwotAnalyses(projectId);
    res.json(analyses);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/swot", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcSwotAnalysisSchema.parse({ ...req.body, projectId });
    const analysis = await compassStorage.createSwotAnalysis(parsed);
    res.status(201).json(analysis);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/swot/:id", async (req: Request, res: Response) => {
  try {
    const analysis = await compassStorage.updateSwotAnalysis(parseInt(req.params.id), req.body);
    if (!analysis) return res.status(404).json({ error: "Análise não encontrada" });
    res.json(analysis);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/swot/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteSwotAnalysis(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Análise não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== SWOT ITEMS ==========
router.get("/swot/:swotId/items", async (req: Request, res: Response) => {
  try {
    const items = await compassStorage.getSwotItems(parseInt(req.params.swotId));
    res.json(items);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/swot/:swotId/items", async (req: Request, res: Response) => {
  try {
    const parsed = insertPcSwotItemSchema.parse({ ...req.body, swotAnalysisId: parseInt(req.params.swotId) });
    const item = await compassStorage.createSwotItem(parsed);
    res.status(201).json(item);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/swot-items/:id", async (req: Request, res: Response) => {
  try {
    const parsed = updatePcSwotItemSchema.parse(req.body);
    const item = await compassStorage.updateSwotItem(parseInt(req.params.id), parsed);
    if (!item) return res.status(404).json({ error: "Item não encontrado" });
    res.json(item);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/swot-items/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteSwotItem(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Item não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CRM STAGES ==========
router.get("/crm/stages", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const stages = await compassStorage.getCrmStages(tenantId);
    res.json(stages);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/crm/stages", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const parsed = insertPcCrmStageSchema.parse({ ...req.body, userId, tenantId });
    const stage = await compassStorage.createCrmStage(parsed);
    res.status(201).json(stage);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

// ========== CRM LEADS ==========
router.get("/crm/leads", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const leads = await compassStorage.getCrmLeads(tenantId);
    res.json(leads);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/crm/leads", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const parsed = insertPcCrmLeadSchema.parse({ ...req.body, userId, tenantId });
    const lead = await compassStorage.createCrmLead(parsed);
    res.status(201).json(lead);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/crm/leads/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const lead = await compassStorage.updateCrmLead(parseInt(req.params.id), tenantId, req.body);
    if (!lead) return res.status(404).json({ error: "Lead não encontrado" });
    res.json(lead);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/crm/leads/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const deleted = await compassStorage.deleteCrmLead(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Lead não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CRM OPPORTUNITIES ==========
router.get("/crm/opportunities", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const opportunities = await compassStorage.getCrmOpportunities(tenantId);
    res.json(opportunities);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/crm/opportunities", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const parsed = insertPcCrmOpportunitySchema.parse({ ...req.body, userId, tenantId });
    const opportunity = await compassStorage.createCrmOpportunity(parsed);
    res.status(201).json(opportunity);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/crm/opportunities/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const opportunity = await compassStorage.updateCrmOpportunity(parseInt(req.params.id), tenantId, req.body);
    if (!opportunity) return res.status(404).json({ error: "Oportunidade não encontrada" });
    res.json(opportunity);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/crm/opportunities/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const deleted = await compassStorage.deleteCrmOpportunity(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Oportunidade não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== CRM ACTIVITIES ==========
router.get("/crm/activities", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const activities = await compassStorage.getCrmActivities(tenantId);
    res.json(activities);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/crm/activities", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any).id;
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const parsed = insertPcCrmActivitySchema.parse({ ...req.body, userId, tenantId });
    const activity = await compassStorage.createCrmActivity(parsed);
    res.status(201).json(activity);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

// ========== DELIVERABLES ==========
router.get("/projects/:projectId/deliverables", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const deliverables = await compassStorage.getDeliverables(projectId);
    res.json(deliverables);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/deliverables", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcDeliverableSchema.parse({ ...req.body, projectId });
    const deliverable = await compassStorage.createDeliverable(parsed);
    res.status(201).json(deliverable);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/deliverables/:id", async (req: Request, res: Response) => {
  try {
    const deliverable = await compassStorage.updateDeliverable(parseInt(req.params.id), req.body);
    if (!deliverable) return res.status(404).json({ error: "Entregável não encontrado" });
    res.json(deliverable);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/deliverables/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteDeliverable(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Entregável não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== TASKS ==========
router.get("/tasks", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const projectId = req.query.projectId ? parseInt(req.query.projectId as string) : undefined;
    if (projectId && !await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const tasks = await compassStorage.getTasks(projectId);
    res.json(tasks);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/tasks", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(400).json({ error: "Sem tenant associado" });
    const userId = (req.user as any).id;
    if (req.body.projectId && !await validateProjectAccess(req.body.projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcTaskSchema.parse({ ...req.body, createdById: userId });
    const task = await compassStorage.createTask(parsed);
    res.status(201).json(task);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/tasks/:id", async (req: Request, res: Response) => {
  try {
    const task = await compassStorage.updateTask(parseInt(req.params.id), req.body);
    if (!task) return res.status(404).json({ error: "Tarefa não encontrada" });
    res.json(task);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/tasks/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteTask(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Tarefa não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PDCA CYCLES ==========
router.get("/pdca/overview/:projectId", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const overview = await compassStorage.getPdcaOverview(projectId);
    res.json(overview);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/pdca", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = req.query.projectId ? parseInt(req.query.projectId as string) : undefined;
    if (projectId && !await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const cycles = await compassStorage.getPdcaCycles(tenantId, projectId);
    res.json(cycles);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/pdca/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const cycle = await compassStorage.getPdcaCycle(parseInt(req.params.id), tenantId);
    if (!cycle) return res.status(404).json({ error: "Ciclo PDCA não encontrado" });
    res.json(cycle);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/pdca", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    if (req.body.projectId && !await validateProjectAccess(req.body.projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcPdcaCycleSchema.parse({ ...req.body, tenantId });
    const cycle = await compassStorage.createPdcaCycle(parsed);
    res.status(201).json(cycle);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/pdca/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const cycle = await compassStorage.updatePdcaCycle(parseInt(req.params.id), tenantId, req.body);
    if (!cycle) return res.status(404).json({ error: "Ciclo PDCA não encontrado" });
    res.json(cycle);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/pdca/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deletePdcaCycle(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Ciclo PDCA não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PDCA ACTIONS ==========
router.get("/pdca/:cycleId/actions", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const cycleId = parseInt(req.params.cycleId);
    const cycle = await compassStorage.getPdcaCycle(cycleId, tenantId);
    if (!cycle) return res.status(404).json({ error: "Ciclo PDCA não encontrado" });
    const actions = await compassStorage.getPdcaActions(cycleId);
    res.json(actions);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/pdca/:cycleId/actions", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const cycleId = parseInt(req.params.cycleId);
    const cycle = await compassStorage.getPdcaCycle(cycleId, tenantId);
    if (!cycle) return res.status(404).json({ error: "Ciclo PDCA não encontrado" });
    const parsed = insertPcPdcaActionSchema.parse({ ...req.body, cycleId });
    const action = await compassStorage.createPdcaAction(parsed);
    res.status(201).json(action);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/pdca/actions/:id", async (req: Request, res: Response) => {
  try {
    const action = await compassStorage.updatePdcaAction(parseInt(req.params.id), req.body);
    if (!action) return res.status(404).json({ error: "Ação não encontrada" });
    res.json(action);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/pdca/actions/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deletePdcaAction(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Ação não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== REQUIREMENTS ==========
router.get("/requirements", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = req.query.projectId ? parseInt(req.query.projectId as string) : undefined;
    if (projectId && !await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const requirements = await compassStorage.getRequirements(tenantId, projectId);
    res.json(requirements);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/requirements/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const requirement = await compassStorage.getRequirement(parseInt(req.params.id), tenantId);
    if (!requirement) return res.status(404).json({ error: "Requisito não encontrado" });
    res.json(requirement);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/requirements", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    if (req.body.projectId && !await validateProjectAccess(req.body.projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcRequirementSchema.parse({ ...req.body, tenantId });
    const requirement = await compassStorage.createRequirement(parsed);
    res.status(201).json(requirement);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/requirements/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const requirement = await compassStorage.updateRequirement(parseInt(req.params.id), tenantId, req.body);
    if (!requirement) return res.status(404).json({ error: "Requisito não encontrado" });
    res.json(requirement);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/requirements/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteRequirement(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Requisito não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== DASHBOARD STATS ==========
router.get("/stats", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.json({ clients: 0, projects: 0, leads: 0, opportunities: 0 });
    
    const [clients, projects] = await Promise.all([
      crmStorage.getClients(),
      compassStorage.getProjects(tenantId)
    ]);
    
    res.json({
      clients: clients.length,
      projects: projects.length,
      leads: 0,
      opportunities: 0,
      activeProjects: projects.filter(p => p.status === 'andamento').length,
      openOpportunities: 0
    });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== INTEGRATION: DIAGNOSTICS TO WORK ITEMS ==========
router.post("/insights/to-work-item", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const { type, sourceId, title, description, projectId, priority = "medium" } = req.body;
    
    if (!type || !sourceId || !title) {
      return res.status(400).json({ error: "Campos obrigatórios: type, sourceId, title" });
    }
    
    const originMap: Record<string, string> = {
      swot: "diagnostic_insight",
      canvas: "diagnostic_insight",
      process: "diagnostic_insight",
      backlog: "backlog_item",
    };
    
    const workItem = await productionStorage.createWorkItem({
      tenantId,
      projectId: projectId || null,
      title,
      description: description || "",
      type: "task",
      status: "backlog",
      priority,
      origin: originMap[type] || "direct",
      originId: sourceId,
    });
    
    res.status(201).json(workItem);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/swot-analyses/:analysisId/items/:itemIndex/to-work-item", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const analysisId = parseInt(req.params.analysisId);
    const itemIndex = parseInt(req.params.itemIndex);
    const swotItems = await compassStorage.getSwotItems(analysisId);
    const swotItem = swotItems[itemIndex];
    if (!swotItem) return res.status(404).json({ error: "Item SWOT não encontrado" });
    
    const typeLabels: Record<string, string> = {
      strength: "Força",
      weakness: "Fraqueza",
      opportunity: "Oportunidade",
      threat: "Ameaça",
    };
    
    const itemTitle = swotItem.title || swotItem.description.slice(0, 80);
    const priorityValue = swotItem.priorityLevel || "medium";
    
    const workItem = await productionStorage.createWorkItem({
      tenantId,
      projectId: req.body.projectId || null,
      title: `[${typeLabels[swotItem.type] || swotItem.type}] ${itemTitle}`,
      description: swotItem.description,
      type: swotItem.type === "weakness" || swotItem.type === "threat" ? "improvement" : "story",
      status: "backlog",
      priority: priorityValue,
      origin: "diagnostic_insight",
      originId: swotItem.id,
      originType: "swot_item",
    });
    
    res.status(201).json(workItem);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/canvas-blocks/:id/to-work-item", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const blockId = parseInt(req.params.id);
    const block = await compassStorage.getCanvasBlock(blockId);
    if (!block) return res.status(404).json({ error: "Bloco Canvas não encontrado" });
    
    const workItem = await productionStorage.createWorkItem({
      tenantId,
      projectId: req.body.projectId || null,
      title: `[Canvas ${block.blockType}] ${block.content?.slice(0, 80) || "Item do Canvas"}`,
      description: block.content || "",
      type: "story",
      status: "backlog",
      priority: "medium",
      origin: "diagnostic_insight",
      originId: blockId,
      originType: "canvas_block",
    });
    
    res.status(201).json(workItem);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/processes/:id/to-work-items", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const processId = parseInt(req.params.id);
    const process = await compassStorage.getProcess(processId);
    if (!process) return res.status(404).json({ error: "Processo não encontrado" });
    
    const steps = await compassStorage.getProcessSteps(processId);
    const workItems = [];
    
    for (const step of steps) {
      if (step.status === "improvement_needed" || step.status === "critical") {
        const workItem = await productionStorage.createWorkItem({
          tenantId,
          projectId: req.body.projectId || null,
          title: `[Melhoria de Processo] ${step.name}`,
          description: `Processo: ${process.name}\n\nEtapa: ${step.name}\n\nDescrição: ${step.description || ""}`,
          type: "improvement",
          status: "backlog",
          priority: step.status === "critical" ? "high" : "medium",
          origin: "diagnostic_insight",
          originId: step.id,
          originType: "process_step",
        });
        workItems.push(workItem);
      }
    }
    
    res.status(201).json({ created: workItems.length, workItems });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== REPORT TEMPLATES ==========
router.get("/report-templates", async (req: Request, res: Response) => {
  try {
    const templates = await compassStorage.getReportTemplates();
    res.json(templates);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/report-templates/:id", async (req: Request, res: Response) => {
  try {
    const template = await compassStorage.getReportTemplate(parseInt(req.params.id));
    if (!template) return res.status(404).json({ error: "Template não encontrado" });
    res.json(template);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/report-templates", async (req: Request, res: Response) => {
  try {
    const parsed = insertPcReportTemplateSchema.parse(req.body);
    const template = await compassStorage.createReportTemplate(parsed);
    res.status(201).json(template);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/report-templates/:id", async (req: Request, res: Response) => {
  try {
    const template = await compassStorage.updateReportTemplate(parseInt(req.params.id), req.body);
    if (!template) return res.status(404).json({ error: "Template não encontrado" });
    res.json(template);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/report-templates/:id", async (req: Request, res: Response) => {
  try {
    const deleted = await compassStorage.deleteReportTemplate(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Template não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== REPORT CONFIGURATIONS ==========
router.get("/report-configurations", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = req.query.projectId ? parseInt(req.query.projectId as string) : undefined;
    const configs = await compassStorage.getReportConfigurations(tenantId, projectId);
    res.json(configs);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/report-configurations/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const config = await compassStorage.getReportConfiguration(parseInt(req.params.id), tenantId);
    if (!config) return res.status(404).json({ error: "Configuração não encontrada" });
    res.json(config);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/report-configurations", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const userId = (req.user as any).id;
    const parsed = insertPcReportConfigurationSchema.parse({ ...req.body, tenantId, createdById: userId });
    const config = await compassStorage.createReportConfiguration(parsed);
    res.status(201).json(config);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/report-configurations/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const config = await compassStorage.updateReportConfiguration(parseInt(req.params.id), tenantId, req.body);
    if (!config) return res.status(404).json({ error: "Configuração não encontrada" });
    res.json(config);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/report-configurations/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteReportConfiguration(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Configuração não encontrada" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== GENERATED REPORTS ==========
router.get("/generated-reports", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = req.query.projectId ? parseInt(req.query.projectId as string) : undefined;
    const reports = await compassStorage.getGeneratedReports(tenantId, projectId);
    res.json(reports);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/generated-reports/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const report = await compassStorage.getGeneratedReport(parseInt(req.params.id), tenantId);
    if (!report) return res.status(404).json({ error: "Relatório não encontrado" });
    res.json(report);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/generated-reports", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const userId = (req.user as any).id;
    const { sections, ...body } = req.body;
    const metadata = { ...(body.metadata || {}), sections: sections || [] };
    const parsed = insertPcGeneratedReportSchema.parse({ ...body, tenantId, generatedBy: userId, status: "pending", metadata });
    const report = await compassStorage.createGeneratedReport(parsed);
    res.status(201).json(report);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.post("/generated-reports/:id/generate", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const reportId = parseInt(req.params.id);
    const report = await compassStorage.getGeneratedReport(reportId, tenantId);
    if (!report) return res.status(404).json({ error: "Relatório não encontrado" });
    
    await compassStorage.updateGeneratedReport(reportId, tenantId, { status: "generating" });
    
    const reportData = report.projectId ? await compassStorage.getProjectReportData(report.projectId) : null;
    if (!reportData) {
      await compassStorage.updateGeneratedReport(reportId, tenantId, { status: "failed" });
      return res.status(404).json({ error: "Dados do projeto não encontrados" });
    }
    
    // Get selected sections from metadata
    const sections = (report.metadata as any)?.sections || [];
    
    // Generate HTML content based on report type and selected sections
    let htmlContent = generateReportContent(report.reportType || "executive_summary", reportData, sections);
    
    await compassStorage.updateGeneratedReport(reportId, tenantId, { 
      status: "completed",
      content: htmlContent,
      updatedAt: new Date(),
    });
    
    const updatedReport = await compassStorage.getGeneratedReport(reportId, tenantId);
    res.json(updatedReport);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// Save edited report content
router.patch("/generated-reports/:id/content", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    
    const reportId = parseInt(req.params.id);
    const { content, name } = req.body;
    
    const updated = await compassStorage.updateGeneratedReport(reportId, tenantId, { 
      content,
      name,
      updatedAt: new Date(),
    });
    
    if (!updated) return res.status(404).json({ error: "Relatório não encontrado" });
    res.json(updated);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// Helper function to generate report content
function generateReportContent(reportType: string, data: any, sections: string[] = []): string {
  const project = data.project;
  const canvasBlocks = data.canvas || [];
  const swotAnalyses = data.swot || [];
  const processes = data.processes || [];
  const requirements = data.requirements || [];
  const pdcaCycles = data.pdca || [];
  
  // If no sections specified, include all for full_diagnostic
  const includedSections = sections.length > 0 ? sections : [
    "project_info", "canvas_atual", "canvas_sistemico", "swot", "processes", "pdca", "requirements"
  ];
  
  const shouldInclude = (section: string) => includedSections.includes(section);
  
  const blockTypeLabels: Record<string, string> = {
    key_partners: "Parceiros-Chave",
    key_activities: "Atividades-Chave",
    key_resources: "Recursos-Chave",
    value_propositions: "Proposta de Valor",
    customer_relationships: "Relacionamento com Clientes",
    channels: "Canais",
    customer_segments: "Segmentos de Clientes",
    cost_structure: "Estrutura de Custos",
    revenue_streams: "Fontes de Receita",
  };
  
  let html = `<div style="font-family: 'Segoe UI', Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px;">`;
  
  // Cover Page
  html += `
    <div style="text-align: center; margin-bottom: 40px; padding: 40px 0; border-bottom: 3px solid #3b82f6;">
      <h1 style="font-size: 28px; color: #1e293b; margin-bottom: 10px;">${project?.name || "Projeto"}</h1>
      <h2 style="font-size: 20px; color: #64748b; font-weight: normal;">${
        reportType === "executive_summary" ? "Sumário Executivo" :
        reportType === "full_diagnostic" ? "Diagnóstico Completo" :
        reportType === "swot_report" ? "Análise SWOT" : "Relatório"
      }</h2>
      <p style="color: #94a3b8; margin-top: 20px;">Gerado em: ${new Date().toLocaleDateString('pt-BR')}</p>
    </div>
  `;
  
  // Project Description
  if (shouldInclude("project_info") && project?.description) {
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Descrição do Projeto</h3>
        <p style="color: #475569; line-height: 1.6;">${project.description}</p>
      </div>
    `;
  }
  
  // Canvas Blocks (for all report types) - Show all 9 BMC blocks
  const allBlockTypes = [
    "key_partners",
    "key_activities", 
    "key_resources",
    "value_propositions",
    "customer_relationships",
    "channels",
    "customer_segments",
    "cost_structure",
    "revenue_streams",
  ];
  
  // Group canvas blocks by level (intencao = atual, sistemico)
  const canvasByLevel: Record<string, any[]> = {};
  for (const block of canvasBlocks) {
    const level = block.level || "intencao";
    if (!canvasByLevel[level]) canvasByLevel[level] = [];
    canvasByLevel[level].push(block);
  }
  
  // Canvas Atual (Intenção)
  const canvasAtual = canvasByLevel["intencao"] || [];
  if (shouldInclude("canvas_atual") && canvasAtual.length > 0) {
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Canvas BMC - Atual (Intenção)</h3>
        <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 15px;">
    `;
    
    for (const blockType of allBlockTypes) {
      const block = canvasAtual.find((b: any) => b.blockType === blockType);
      const hasContent = block && (block.content || block.title);
      html += `
        <div style="padding: 12px; background: ${hasContent ? '#f0f9ff' : '#f8fafc'}; border-radius: 8px; border: 1px solid ${hasContent ? '#3b82f6' : '#e2e8f0'}; min-height: 80px;">
          <h5 style="color: ${hasContent ? '#1e40af' : '#64748b'}; margin: 0 0 8px 0; font-size: 12px; text-transform: uppercase;">${blockTypeLabels[blockType]}</h5>
          ${block ? `
            ${block.title ? `<p style="font-weight: 600; color: #334155; margin: 0 0 5px 0; font-size: 13px;">${block.title}</p>` : ""}
            <p style="color: #475569; line-height: 1.4; margin: 0; font-size: 13px;">${block.content || '<em style="color: #94a3b8;">Não preenchido</em>'}</p>
          ` : `<p style="color: #94a3b8; font-style: italic; margin: 0; font-size: 13px;">Não preenchido</p>`}
        </div>
      `;
    }
    html += `</div></div>`;
  }
  
  // Canvas Sistêmico (if exists)
  const canvasSistemico = canvasByLevel["sistemico"] || [];
  if (shouldInclude("canvas_sistemico") && canvasSistemico.length > 0) {
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Canvas BMC - Sistêmico</h3>
        <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 15px;">
    `;
    
    for (const blockType of allBlockTypes) {
      const block = canvasSistemico.find((b: any) => b.blockType === blockType);
      const hasContent = block && (block.content || block.title);
      html += `
        <div style="padding: 12px; background: ${hasContent ? '#fef3c7' : '#f8fafc'}; border-radius: 8px; border: 1px solid ${hasContent ? '#f59e0b' : '#e2e8f0'}; min-height: 80px;">
          <h5 style="color: ${hasContent ? '#92400e' : '#64748b'}; margin: 0 0 8px 0; font-size: 12px; text-transform: uppercase;">${blockTypeLabels[blockType]}</h5>
          ${block ? `
            ${block.title ? `<p style="font-weight: 600; color: #334155; margin: 0 0 5px 0; font-size: 13px;">${block.title}</p>` : ""}
            <p style="color: #475569; line-height: 1.4; margin: 0; font-size: 13px;">${block.content || '<em style="color: #94a3b8;">Não preenchido</em>'}</p>
          ` : `<p style="color: #94a3b8; font-style: italic; margin: 0; font-size: 13px;">Não preenchido</p>`}
        </div>
      `;
    }
    html += `</div></div>`;
  }
  
  // SWOT Analysis
  if (shouldInclude("swot") && swotAnalyses.length > 0) {
    const swotTypeLabels: Record<string, { label: string; color: string }> = {
      strength: { label: "Forças", color: "#22c55e" },
      weakness: { label: "Fraquezas", color: "#ef4444" },
      opportunity: { label: "Oportunidades", color: "#3b82f6" },
      threat: { label: "Ameaças", color: "#f59e0b" },
    };
    
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Análise SWOT</h3>
    `;
    
    for (const swot of swotAnalyses) {
      html += `
        <div style="margin: 15px 0;">
          <h4 style="color: #1e293b;">${swot.name || "Análise"}</h4>
          ${swot.description ? `<p style="color: #475569; margin-bottom: 15px;">${swot.description}</p>` : ""}
      `;
      
      if (swot.items && swot.items.length > 0) {
        const groupedItems: Record<string, any[]> = {};
        for (const item of swot.items) {
          const type = item.itemType || "other";
          if (!groupedItems[type]) groupedItems[type] = [];
          groupedItems[type].push(item);
        }
        
        html += `<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px;">`;
        for (const [type, items] of Object.entries(groupedItems)) {
          const typeInfo = swotTypeLabels[type] || { label: type, color: "#64748b" };
          html += `
            <div style="padding: 15px; background: #f8fafc; border-radius: 8px; border-left: 4px solid ${typeInfo.color};">
              <h5 style="color: ${typeInfo.color}; margin: 0 0 10px 0;">${typeInfo.label}</h5>
              <ul style="margin: 0; padding-left: 20px; color: #475569;">
                ${items.map((i: any) => `<li>${i.content || i.title || ""}</li>`).join("")}
              </ul>
            </div>
          `;
        }
        html += `</div>`;
      }
      html += `</div>`;
    }
    html += `</div>`;
  }
  
  // Processes
  if (shouldInclude("processes") && processes.length > 0) {
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Processos Mapeados</h3>
    `;
    
    for (const process of processes) {
      html += `
        <div style="margin: 15px 0; padding: 15px; background: #f0fdf4; border-radius: 8px; border-left: 4px solid #22c55e;">
          <h4 style="color: #1e293b; margin: 0 0 8px 0;">${process.name}</h4>
          ${process.description ? `<p style="color: #475569; margin: 0;">${process.description}</p>` : ""}
        </div>
      `;
    }
    html += `</div>`;
  }
  
  // Requirements
  if (shouldInclude("requirements") && requirements.length > 0) {
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Requisitos</h3>
        <ul style="color: #475569; line-height: 1.8;">
    `;
    
    for (const req of requirements) {
      html += `<li><strong>${req.title}</strong>: ${req.description || ""}</li>`;
    }
    html += `</ul></div>`;
  }
  
  // PDCA Cycles
  if (shouldInclude("pdca") && pdcaCycles.length > 0) {
    const pdcaStatusLabels: Record<string, { label: string; color: string }> = {
      plan: { label: "Planejar", color: "#3b82f6" },
      do: { label: "Executar", color: "#f59e0b" },
      check: { label: "Verificar", color: "#8b5cf6" },
      act: { label: "Agir", color: "#22c55e" },
    };
    
    html += `
      <div style="margin-bottom: 30px;">
        <h3 style="color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">Ciclos PDCA</h3>
    `;
    
    for (const cycle of pdcaCycles) {
      const statusInfo = pdcaStatusLabels[cycle.status] || { label: cycle.status, color: "#64748b" };
      html += `
        <div style="margin: 15px 0; padding: 15px; background: #fefce8; border-radius: 8px; border-left: 4px solid ${statusInfo.color};">
          <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
            <h4 style="color: #1e293b; margin: 0;">${cycle.title}</h4>
            <span style="background: ${statusInfo.color}; color: white; padding: 4px 12px; border-radius: 12px; font-size: 12px;">${statusInfo.label}</span>
          </div>
          ${cycle.description ? `<p style="color: #475569; margin: 0;">${cycle.description}</p>` : ""}
          ${cycle.actions && cycle.actions.length > 0 ? `
            <div style="margin-top: 10px;">
              <p style="color: #64748b; font-size: 14px; margin-bottom: 5px;">Ações:</p>
              <ul style="margin: 0; padding-left: 20px; color: #475569;">
                ${cycle.actions.map((a: any) => `<li>${a.title || a.description || ""}</li>`).join("")}
              </ul>
            </div>
          ` : ""}
        </div>
      `;
    }
    html += `</div>`;
  }
  
  // Footer
  html += `
    <div style="margin-top: 40px; padding-top: 20px; border-top: 2px solid #e2e8f0; text-align: center; color: #94a3b8; font-size: 12px;">
      <p>Relatório gerado automaticamente pelo Arcádia Suite - Process Compass</p>
    </div>
  </div>`;
  
  return html;
}

router.delete("/generated-reports/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteGeneratedReport(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Relatório não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== REPORT DATA AGGREGATION ==========
router.get("/projects/:id/report-data", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.id);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const data = await compassStorage.getProjectReportData(projectId);
    if (!data) return res.status(404).json({ error: "Projeto não encontrado" });
    res.json(data);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== ERP ADHERENCE ==========
router.get("/erp-modules", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const modules = await compassStorage.getErpModules(tenantId);
    res.json(modules);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/erp-modules", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const parsed = insertPcErpModuleSchema.parse({ ...req.body, tenantId });
    const module = await compassStorage.createErpModule(parsed);
    res.status(201).json(module);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/erp-modules/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const module = await compassStorage.updateErpModule(parseInt(req.params.id), tenantId, req.body);
    if (!module) return res.status(404).json({ error: "Módulo não encontrado" });
    res.json(module);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/erp-modules/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteErpModule(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Módulo não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ERP Requirements
router.get("/projects/:projectId/erp-requirements", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const requirements = await compassStorage.getErpRequirements(projectId);
    res.json(requirements);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/projects/:projectId/erp-adherence-stats", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const stats = await compassStorage.getErpAdherenceStats(projectId);
    res.json(stats);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/erp-requirements", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcErpRequirementSchema.parse({ ...req.body, tenantId, projectId });
    const requirement = await compassStorage.createErpRequirement(parsed);
    res.status(201).json(requirement);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/erp-requirements/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const requirement = await compassStorage.updateErpRequirement(parseInt(req.params.id), tenantId, req.body);
    if (!requirement) return res.status(404).json({ error: "Requisito não encontrado" });
    res.json(requirement);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/erp-requirements/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteErpRequirement(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Requisito não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ERP Parameterization Topics
router.get("/projects/:projectId/erp-parameterization", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const topics = await compassStorage.getErpParameterizationTopics(projectId);
    const topicsWithItems = await Promise.all(
      topics.map(async (topic) => ({
        ...topic,
        items: await compassStorage.getErpParameterizationItems(topic.id),
      }))
    );
    res.json(topicsWithItems);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/erp-parameterization", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    if (!await validateProjectAccess(projectId, tenantId)) {
      return res.status(404).json({ error: "Projeto não encontrado" });
    }
    const parsed = insertPcErpParameterizationTopicSchema.parse({ ...req.body, tenantId, projectId });
    const topic = await compassStorage.createErpParameterizationTopic(parsed);
    res.status(201).json(topic);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/erp-parameterization-topics/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const topic = await compassStorage.updateErpParameterizationTopic(parseInt(req.params.id), tenantId, req.body);
    if (!topic) return res.status(404).json({ error: "Tópico não encontrado" });
    res.json(topic);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/erp-parameterization-topics/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteErpParameterizationTopic(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Tópico não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ERP Parameterization Items
router.post("/erp-parameterization-topics/:topicId/items", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const parsed = insertPcErpParameterizationItemSchema.parse({ ...req.body, topicId: parseInt(req.params.topicId) });
    const item = await compassStorage.createErpParameterizationItem(parsed);
    res.status(201).json(item);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/erp-parameterization-items/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const item = await compassStorage.updateErpParameterizationItem(parseInt(req.params.id), tenantId, req.body);
    if (!item) return res.status(404).json({ error: "Item não encontrado" });
    res.json(item);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/erp-parameterization-items/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.deleteErpParameterizationItem(parseInt(req.params.id), tenantId);
    if (!deleted) return res.status(404).json({ error: "Item não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROJECT TEAM MEMBERS ==========
router.get("/projects/:projectId/team", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const members = await compassStorage.getProjectTeamMembers(projectId);
    res.json(members);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/team", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const member = await compassStorage.addProjectTeamMember({ ...req.body, projectId });
    res.status(201).json(member);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/team/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const deleted = await compassStorage.removeProjectTeamMember(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Membro não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROJECT TASKS ==========
router.get("/projects/:projectId/tasks", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const tasks = await compassStorage.getProjectTasks(projectId);
    res.json(tasks);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/tasks", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const task = await compassStorage.createProjectTask({ ...req.body, projectId, status: "pending" });
    res.status(201).json(task);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.patch("/tasks/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const task = await compassStorage.updateProjectTask(parseInt(req.params.id), req.body);
    if (!task) return res.status(404).json({ error: "Tarefa não encontrada" });
    res.json(task);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

// ========== PROJECT FILES ==========
import multer from "multer";
import path from "path";
import fs from "fs";

const uploadDir = path.join(process.cwd(), "uploads", "project-files");
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

const projectFileStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1E9);
    cb(null, uniqueSuffix + "-" + file.originalname);
  }
});

const projectFileUpload = multer({ storage: projectFileStorage, limits: { fileSize: 50 * 1024 * 1024 } });

router.get("/projects/:projectId/files", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const files = await compassStorage.getProjectFiles(projectId);
    res.json(files);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.post("/projects/:projectId/files", projectFileUpload.single("file"), async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    
    if (!req.file) return res.status(400).json({ error: "Nenhum arquivo enviado" });
    
    const file = await compassStorage.createProjectFile({
      projectId,
      name: req.file.filename,
      originalName: req.file.originalname,
      mimeType: req.file.mimetype,
      size: req.file.size,
      url: `/uploads/project-files/${req.file.filename}`,
    });
    res.status(201).json(file);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

router.delete("/files/:id", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const file = await compassStorage.getProjectFile(parseInt(req.params.id));
    if (file) {
      const filePath = path.join(uploadDir, file.name);
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }
    const deleted = await compassStorage.deleteProjectFile(parseInt(req.params.id));
    if (!deleted) return res.status(404).json({ error: "Arquivo não encontrado" });
    res.status(204).send();
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// ========== PROJECT HISTORY ==========
router.get("/projects/:projectId/history", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const history = await compassStorage.getProjectHistory(projectId);
    res.json(history);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.put("/projects/:projectId/history", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });
    const history = await compassStorage.saveProjectHistory({ projectId, content: req.body.content });
    res.json(history);
  } catch (error: any) {
    res.status(400).json({ error: error.message });
  }
});

// ========== AI BRIEFING & HEALTH SCORE ==========

router.post("/projects/:projectId/ai-brief", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });

    const project = await compassStorage.getProject(projectId, tenantId);
    const tasks = await compassStorage.getTasks(projectId);
    const pdcaCycles = await compassStorage.getPdcaCycles(tenantId, projectId);

    const openTasks = tasks.filter((t: any) => t.status !== "done" && t.status !== "completed");
    const overdue = tasks.filter((t: any) => t.dueDate && new Date(t.dueDate) < new Date() && t.status !== "done");
    const pdcaOpen = pdcaCycles.filter((c: any) => c.status === "open" || c.status === "in_progress");

    const OpenAI = (await import("openai")).default;
    const openai = new OpenAI({
      apiKey: process.env.AI_INTEGRATIONS_OPENAI_API_KEY,
      baseURL: process.env.AI_INTEGRATIONS_OPENAI_BASE_URL,
      timeout: 30000,
    });

    const prompt = `Você é um consultor de gestão de projetos. Analise o projeto abaixo e gere um briefing executivo em português.

PROJETO: ${project?.name}
DESCRIÇÃO: ${project?.description || "Não informada"}
STATUS: ${project?.status}
FASE: ${project?.currentPhase || "Não definida"}

RESUMO DE TAREFAS:
- Total: ${tasks.length}
- Em aberto: ${openTasks.length}
- Atrasadas: ${overdue.length}

PDCA ATIVOS: ${pdcaOpen.length}

${overdue.length > 0 ? `TAREFAS ATRASADAS:\n${overdue.slice(0, 5).map((t: any) => `- ${t.title} (responsável: ${t.assignedTo || "não atribuído"})`).join("\n")}` : ""}

Gere um briefing com:
1. **Situação atual** (2-3 linhas)
2. **Principais riscos** (lista com até 3 itens)
3. **Ações prioritárias** (lista com até 5 ações, cada uma com responsável sugerido e prazo)
4. **Score de saúde** (0-100 com justificativa)

Seja direto e objetivo.`;

    const response = await openai.chat.completions.create({
      model: "gpt-4o-mini",
      messages: [{ role: "user", content: prompt }],
      max_tokens: 800,
      temperature: 0.3,
    });

    const briefText = response.choices[0]?.message?.content || "";

    // Extract health score from response
    const scoreMatch = briefText.match(/score[^\d]*(\d{1,3})/i) || briefText.match(/(\d{1,3})[^\d]*\//);
    const healthScore = scoreMatch ? Math.min(100, Math.max(0, parseInt(scoreMatch[1]))) : null;

    res.json({
      projectId,
      brief: briefText,
      healthScore,
      meta: {
        totalTasks: tasks.length,
        openTasks: openTasks.length,
        overdueTasks: overdue.length,
        activePdca: pdcaOpen.length,
        generatedAt: new Date().toISOString(),
      },
    });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

router.get("/projects/:projectId/health", async (req: Request, res: Response) => {
  try {
    const tenantId = await getTenantId(req);
    if (!tenantId) return res.status(403).json({ error: "Tenant não encontrado" });
    const projectId = parseInt(req.params.projectId);
    const hasAccess = await validateProjectAccess(projectId, tenantId);
    if (!hasAccess) return res.status(403).json({ error: "Acesso negado ao projeto" });

    const tasks = await compassStorage.getTasks(projectId);
    const pdcaCycles = await compassStorage.getPdcaCycles(tenantId, projectId);

    const total = tasks.length || 1;
    const done = tasks.filter((t: any) => t.status === "done" || t.status === "completed").length;
    const overdue = tasks.filter((t: any) => t.dueDate && new Date(t.dueDate) < new Date() && t.status !== "done").length;
    const pdcaComplete = pdcaCycles.filter((c: any) => c.status === "completed").length;
    const pdcaTotal = pdcaCycles.length || 1;

    const completionScore = (done / total) * 40;
    const overdueScore = Math.max(0, 30 - (overdue / total) * 30);
    const pdcaScore = (pdcaComplete / pdcaTotal) * 30;
    const healthScore = Math.round(completionScore + overdueScore + pdcaScore);

    const level = healthScore >= 80 ? "saudável" : healthScore >= 50 ? "atenção" : "crítico";
    const color = healthScore >= 80 ? "green" : healthScore >= 50 ? "yellow" : "red";

    res.json({
      projectId,
      healthScore,
      level,
      color,
      breakdown: {
        completion: { score: Math.round(completionScore), weight: "40%", tasks: `${done}/${tasks.length}` },
        timeliness: { score: Math.round(overdueScore), weight: "30%", overdue },
        pdca: { score: Math.round(pdcaScore), weight: "30%", cycles: `${pdcaComplete}/${pdcaCycles.length}` },
      },
    });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

export default router;
