// ===========================================================
// DEAD SAILOR · PROJECT DOCK · MOCK DATA
// ===========================================================

window.DS_DATA = {
  currentClient: {
    id: 'aurora',
    name: 'Aurora Studio',
    contact: 'Helena Vidal',
    email: 'helena@aurorastudio.com',
    avatar: 'A',
  },
  team: [
    { id: 'denis', name: 'Denis Paganini', initials: 'DP', role: 'Direção criativa' },
    { id: 'marina', name: 'Marina Costa', initials: 'MC', role: 'Produção' },
  ],
  clients: [
    { id: 'aurora', name: 'Aurora Studio', city: 'São Paulo · BR', projects: 1 },
    { id: 'lume', name: 'Studio Lume', city: 'Rio de Janeiro · BR', projects: 1 },
    { id: 'terracotta', name: 'Terracotta', city: 'Belo Horizonte · BR', projects: 1 },
    { id: 'orbit', name: 'Orbit', city: 'Curitiba · BR', projects: 1 },
    { id: 'casa-norte', name: 'Casa Norte', city: 'Recife · BR', projects: 1 },
  ],

  // Client-side projects (only Aurora's, as the "current" client)
  clientProjects: [
    {
      id: 'rebranding-aurora',
      title: 'Rebranding Aurora Studio',
      titleShort: 'Rebranding Aurora',
      service: 'Branding Estratégico',
      status: 'approval',
      statusLabel: 'Em aprovação',
      progress: 65,
      start: '18 mai 2026',
      end: '24 jun 2026',
      nextDeadline: '28 mai 2026',
      lead: 'Denis Paganini',
      leadInitials: 'DP',
      territory: 'DS / TERRITORY 014',
      coord: '23°33′S · 46°38′W',
      scope: 'Desenvolvimento de nova identidade visual para reposicionamento da Aurora Studio, incluindo território conceitual, identidade visual principal, aplicações digitais e brand guide final.',
      revisionsTotal: 2,
      revisionsUsed: 1,
      deliverables: [
        { id: 'd1', n: '01', name: 'Conceito Estratégico', status: 'approved', statusLabel: 'Aprovado', deadline: '20 mai 2026', versions: 2, current: 'V02' },
        { id: 'd2', n: '02', name: 'Identidade Visual Principal', status: 'waiting', statusLabel: 'Aguardando aprovação', deadline: '28 mai 2026', versions: 2, current: 'V02', file: 'KV_AuroraStudio_V02.pdf', primary: true,
          note: 'Nesta segunda versão, refinamos a composição tipográfica, reduzimos a presença dos elementos gráficos secundários e aproximamos a identidade do território premium aprovado.' },
        { id: 'd3', n: '03', name: 'Sistema Gráfico e Aplicações', status: 'production', statusLabel: 'Em produção', deadline: '05 jun 2026', versions: 1, current: 'V01' },
        { id: 'd4', n: '04', name: 'Brand Guide Final', status: 'idle', statusLabel: 'Não iniciado', deadline: '24 jun 2026', versions: 0, current: '—' },
      ],
      finalFiles: [
        { name: 'Logo_Principal_Aurora.zip', kind: 'ZIP', size: '42 MB', date: '25 mai 2026', related: 'Identidade Visual', icon: 'ZIP' },
        { name: 'Manual_de_Marca_Aurora.pdf', kind: 'PDF', size: '18 MB', date: '25 mai 2026', related: 'Brand Guide', icon: 'PDF' },
        { name: 'Kit_Social_Media.zip', kind: 'ZIP', size: '128 MB', date: '24 mai 2026', related: 'Sistema Gráfico', icon: 'ZIP' },
        { name: 'Arquivos_Editaveis.zip', kind: 'ZIP', size: '512 MB', date: '24 mai 2026', related: 'Identidade Visual', icon: 'ZIP' },
      ],
      conversation: [
        { who: 'ds', name: 'Denis · Dead Sailor', when: '25 mai · 09:14', body: 'Acabamos de enviar a versão 02 do Key Visual. Refinamos a composição tipográfica e reduzimos os elementos secundários, conforme conversa de quinta.' },
        { who: 'client', name: 'Helena · Aurora', when: '25 mai · 11:42', body: 'Recebido. Vou analisar com o time hoje à tarde e devolvo até o fim do dia.' },
        { who: 'ds', name: 'Denis · Dead Sailor', when: '25 mai · 12:01', body: 'Perfeito. Qualquer dúvida sobre as decisões, marca aqui no portal — fica registrado junto da entrega.' },
      ],
      activity: [
        { kind: 'send', txt: 'Key Visual V02 enviado para aprovação.', who: 'Denis', when: '25 mai · 09:14' },
        { kind: 'approve', txt: 'Conceito estratégico aprovado pela Aurora.', who: 'Helena', when: '22 mai · 16:30' },
        { kind: 'send', txt: 'Conceito estratégico V02 enviado.', who: 'Denis', when: '22 mai · 10:08' },
        { kind: 'note', txt: 'Referências visuais adicionadas ao território.', who: 'Helena', when: '20 mai · 14:00' },
        { kind: 'check', txt: 'Briefing aprovado pela equipe.', who: 'Dead Sailor', when: '19 mai · 09:45' },
      ],
    },
    {
      id: 'campanha-inverno',
      title: 'Campanha Lançamento Coleção Inverno',
      titleShort: 'Coleção Inverno',
      service: 'Direção Criativa',
      status: 'production',
      statusLabel: 'Em produção',
      progress: 34,
      start: '12 mai 2026',
      end: '04 jul 2026',
      nextDeadline: '04 jun 2026',
      lead: 'Marina Costa',
      leadInitials: 'MC',
      territory: 'DS / TERRITORY 015',
      coord: '23°34′S · 46°39′W',
      scope: 'Direção criativa, conceito, produção fotográfica e desdobramentos para a coleção de inverno da Aurora Studio.',
      revisionsTotal: 2,
      revisionsUsed: 0,
      deliverables: [],
      finalFiles: [],
      conversation: [],
      activity: [],
    },
  ],

  // Admin projects (broader portfolio)
  adminProjects: [
    { id: 'rebranding-aurora', name: 'Rebranding Aurora Studio', client: 'Aurora Studio', service: 'Branding', status: 'approval', statusLabel: 'Em aprovação', deadline: '28 mai', lead: 'Denis', leadInitials: 'DP', priority: 'signal' },
    { id: 'campanha-terracotta', name: 'Campanha Terracotta', client: 'Terracotta', service: 'Campanha', status: 'review', statusLabel: 'Em revisão', deadline: '29 mai', lead: 'Denis', leadInitials: 'DP', priority: 'high' },
    { id: 'website-lume', name: 'Website Lume', client: 'Studio Lume', service: 'Website', status: 'brief-received', statusLabel: 'Briefing recebido', deadline: 'A definir', lead: 'Marina', leadInitials: 'MC', priority: 'signal' },
    { id: 'brand-guide-orbit', name: 'Brand Guide Orbit', client: 'Orbit', service: 'Branding', status: 'production', statusLabel: 'Em produção', deadline: '04 jun', lead: 'Denis', leadInitials: 'DP', priority: 'med' },
    { id: 'editorial-casa-norte', name: 'Editorial Casa Norte', client: 'Casa Norte', service: 'Editorial', status: 'final', statusLabel: 'Entrega final', deadline: '27 mai', lead: 'Marina', leadInitials: 'MC', priority: 'high' },
    { id: 'campanha-inverno', name: 'Coleção Inverno Aurora', client: 'Aurora Studio', service: 'Direção Criativa', status: 'production', statusLabel: 'Em produção', deadline: '04 jun', lead: 'Marina', leadInitials: 'MC', priority: 'med' },
    { id: 'naming-orbit', name: 'Naming Orbit Ventures', client: 'Orbit', service: 'Naming', status: 'planning', statusLabel: 'Em planejamento', deadline: '10 jun', lead: 'Denis', leadInitials: 'DP', priority: 'med' },
    { id: 'social-terracotta', name: 'Social Kit Terracotta', client: 'Terracotta', service: 'Social', status: 'final', statusLabel: 'Entrega final', deadline: '30 mai', lead: 'Marina', leadInitials: 'MC', priority: 'signal' },
  ],

  // Briefings inbox (admin)
  briefingsInbox: [
    {
      id: 'b-lume',
      client: 'Studio Lume',
      project: 'Novo website institucional',
      service: 'Website',
      received: 'Recebido hoje · 10:42',
      receivedShort: 'Hoje',
      attachments: 6,
      status: 'in-analysis', statusLabel: 'Em análise',
      priority: 'signal',
    },
    {
      id: 'b-orbit',
      client: 'Orbit',
      project: 'Campanha de lançamento',
      service: 'Campanha',
      received: 'Recebido ontem · 17:08',
      receivedShort: 'Ontem',
      attachments: 3,
      status: 'awaiting', statusLabel: 'Aguardando análise',
      priority: 'med',
    },
    {
      id: 'b-casa-norte',
      client: 'Casa Norte',
      project: 'Editorial de coleção',
      service: 'Editorial',
      received: 'Há 3 dias',
      receivedShort: 'Há 3d',
      attachments: 2,
      status: 'addendum', statusLabel: 'Complemento solicitado',
      priority: 'med',
    },
  ],

  // The full brief for Studio Lume — used in admin briefing analysis
  briefingLume: {
    id: 'b-lume',
    client: 'Studio Lume',
    project: 'Novo Website Institucional',
    service: 'Website',
    received: '25 mai 2026 · 10:42',
    status: 'in-analysis',
    statusLabel: 'Em análise',
    blocks: [
      {
        n: '01', title: 'Contexto da empresa',
        qa: [
          { q: 'Conte um pouco sobre sua empresa.', a: 'Studio Lume é um escritório de arquitetura e interiores fundado em 2017, em São Paulo, com foco em projetos residenciais e culturais de alto padrão. Atendemos hoje principalmente clientes finais e colecionadores.' },
          { q: 'Qual problema este projeto precisa resolver?', a: 'Nosso site atual não reflete o nível de sofisticação dos projetos que entregamos. Precisamos de uma vitrine que sustente conversas com clientes internacionais e veículos de imprensa especializada.' },
          { q: 'O que motivou esta contratação agora?', a: 'Vamos publicar três projetos novos no segundo semestre e queremos estrear o site junto com eles.' },
        ]
      },
      {
        n: '02', title: 'Objetivos',
        qa: [
          { q: 'Qual é o principal objetivo deste projeto?', a: 'Posicionar o Studio Lume como referência em arquitetura contemporânea brasileira no mercado internacional.' },
          { q: 'Como você saberá que este trabalho teve sucesso?', a: 'Aumento de contatos qualificados via site, aparições em veículos como Architectural Digest e Wallpaper, e tempo de permanência maior nas páginas de projeto.' },
          { q: 'Há uma data importante?', a: 'Lançamento desejado: agosto de 2026, alinhado à publicação dos três projetos novos.' },
        ]
      },
      {
        n: '03', title: 'Público',
        qa: [
          { q: 'Para quem este projeto será criado?', a: 'Clientes finais (alto padrão), curadores, jornalistas especializados em arquitetura e design, e parceiros internacionais.' },
          { q: 'O que esse público valoriza?', a: 'Curadoria, repertório, narrativa visual sólida, fotografia de qualidade, atenção aos detalhes.' },
        ]
      },
      {
        n: '04', title: 'Referências',
        qa: [
          { q: 'Marcas e sites que inspiram?', a: 'Vincent Van Duysen, Studio KO, Hub of Huts, 6a architects — referências de tom mais editorial do que comercial.' },
          { q: 'O que deve ser evitado?', a: 'Visual muito tecnológico, sliders animados, vídeos de fundo. Nada de azul corporativo.' },
        ],
        links: [
          { label: 'Site atual', url: 'studiolume.com.br' },
          { label: 'Referência visual 01', url: 'vincentvanduysen.com' },
          { label: 'Concorrente principal', url: 'studioko.fr' },
        ]
      },
      {
        n: '05', title: 'Entregáveis solicitados',
        qa: [
          { q: 'O que precisa ser criado?', a: 'Arquitetura de informação, redesign completo (home, projetos, sobre, contato), tratamento editorial das imagens de projeto, micro-interações.' },
          { q: 'Especificações técnicas?', a: 'CMS leve para que a equipe interna publique novos projetos. Otimização para imagens em alta resolução. Versão em inglês.' },
        ]
      },
      {
        n: '06', title: 'Prazos desejados',
        qa: [
          { q: 'Quando precisa estar pronto?', a: 'Lançamento previsto para 04 ago 2026. Etapas internas: arquitetura até 02 jun, wireframe até 08 jun, layout home até 16 jun.' },
        ]
      },
      {
        n: '07', title: 'Observações',
        qa: [
          { q: 'Algo mais que devemos saber?', a: 'Temos disponibilidade para 2 rodadas de aprovação por entregável, e gostaríamos de incluir um encontro presencial antes do início.' },
        ]
      },
    ],
    files: [
      { name: 'logo_studiolume.svg', size: '42 KB', icon: 'SVG' },
      { name: 'referencias-site.pdf', size: '12 MB', icon: 'PDF' },
      { name: 'fotos-produtos.zip', size: '328 MB', icon: 'ZIP' },
      { name: 'apresentacao-marca.pdf', size: '8 MB', icon: 'PDF' },
    ],
  },

  // Deliverable plan for Studio Lume (admin planning view)
  lumePlan: [
    { id: 'p1', name: 'Arquitetura de conteúdo', deadline: '02 jun 2026', revisions: 1 },
    { id: 'p2', name: 'Wireframe principal', deadline: '08 jun 2026', revisions: 2 },
    { id: 'p3', name: 'Layout visual — Home', deadline: '16 jun 2026', revisions: 2 },
    { id: 'p4', name: 'Layout páginas internas', deadline: '22 jun 2026', revisions: 2 },
    { id: 'p5', name: 'Entrega final organizada', deadline: '25 jun 2026', revisions: 0 },
  ],

  // Admin agenda mock
  agenda: [
    { wk: 'SEG', d: '25', today: true, events: [
      { time: '09:00', label: 'Entrega Key Visual · Aurora', tone: 'on' },
      { time: '14:30', label: 'Análise briefing Studio Lume', tone: 'on' },
    ]},
    { wk: 'TER', d: '26', events: [
      { time: '11:00', label: 'Reunião conceito · Orbit', tone: 'on' },
    ]},
    { wk: 'QUA', d: '27', events: [
      { time: '17:00', label: 'Entrega final · Editorial Casa Norte', tone: 'on' },
    ]},
    { wk: 'QUI', d: '28', events: [
      { time: '12:00', label: 'Aprovação cliente · Aurora KV', tone: 'on' },
      { time: '16:00', label: 'Apresentação · Terracotta', tone: 'on' },
    ]},
    { wk: 'SEX', d: '29', events: [
      { time: '10:00', label: 'Revisão interna · Coleção Inverno', tone: 'muted' },
    ]},
  ],

  // Priority actions for admin home
  prio: [
    { pin: 'signal', ttl: <>Analisar briefing — <em>Studio Lume</em></>, meta: 'Website · 6 anexos', when: 'Recebido hoje' },
    { pin: 'warn', ttl: <>Revisão solicitada — <em>Campanha Terracotta</em></>, meta: 'V02 enviada · cliente pediu ajustes', when: 'Há 2 horas' },
    { pin: 'signal', ttl: <>Entrega prevista — <em>Branding Casa Norte</em></>, meta: 'Final · arquivos prontos', when: 'Amanhã' },
    { pin: 'muted', ttl: <>Cliente aguardando aprovação de prazo — <em>Projeto Orbit</em></>, meta: 'Cronograma proposto', when: 'Há 1 dia' },
  ],

  // Admin overview stats
  adminStats: [
    { l: 'Projetos ativos', v: '12', desc: '02 acima do prazo planejado', trend: '+2' },
    { l: 'Briefings na fila', v: '3', desc: '01 com complemento solicitado' },
    { l: 'Aprovações pendentes', v: '5', desc: 'Aurora · Terracotta · Orbit' },
    { l: 'Revisões em curso', v: '2', desc: 'Terracotta · Aurora KV' },
    { l: 'Entregas nesta semana', v: '4', desc: 'Quarta · Quinta · Sexta' },
    { l: 'Em atraso', v: '1', desc: 'Orbit · Brand Guide' },
  ],

  // Client overview stats
  clientStats: [
    { l: 'Projetos ativos', v: '2', desc: 'Branding · Direção Criativa' },
    { l: 'Aprovação pendente', v: '1', desc: 'Key Visual V02 · até 28 mai' },
    { l: 'Em produção', v: '3', desc: 'Sistema gráfico · Aplicações' },
    { l: 'Arquivos finais', v: '4', desc: 'Disponíveis para download' },
  ],

  // Kanban columns
  kanbanColumns: [
    { key: 'brief-new', label: 'Novo briefing', filter: ['brief-received'] },
    { key: 'analysis', label: 'Em análise', filter: ['analysis'] },
    { key: 'planning', label: 'Planejamento', filter: ['planning'] },
    { key: 'production', label: 'Produção', filter: ['production'] },
    { key: 'approval', label: 'Aprovação', filter: ['approval'] },
    { key: 'review', label: 'Revisão', filter: ['review'] },
    { key: 'final', label: 'Entrega final', filter: ['final'] },
    { key: 'done', label: 'Finalizado', filter: ['done'] },
  ],

  // Pre-populated next-moves for client home
  nextMoves: [
    { day: '28', month: 'MAI', urgent: true, ttl: <>Aprovar <em>Key Visual principal</em></>, meta: ['Versão 02', 'Rebranding Aurora'], action: { label: 'Revisar', target: 'approve' } },
    { day: '30', month: 'MAI', ttl: <>Revisar proposta de <em>naming</em></>, meta: ['Coleção Inverno', 'Direção criativa'], action: { label: 'Abrir', target: 'project-campanha-inverno' } },
    { day: '02', month: 'JUN', ttl: <>Download disponível: <em>Brand Guide</em> final</>, meta: ['Estúdio anterior', 'Arquivo de referência'], action: { label: 'Baixar', target: 'files' } },
  ],
};

// ===========================================================
// Data Bridge: tries API first, falls back to DS_DATA
// ===========================================================

function mapDbProject(p) {
  if (!p) return p;
  return {
    ...p,
    title: p.title || 'Novo Projeto',
    titleShort: p.title_short || p.title || 'Projeto',
    service: p.service || 'Branding',
    status: p.status || 'production',
    statusLabel: p.statusLabel || p.status_label || 'Em curso',
    progress: p.progress || 0,
    start: p.start_date || p.start || '—',
    end: p.end_date || p.end || '—',
    nextDeadline: p.next_deadline || p.nextDeadline || '—',
    lead: p.lead || 'Dead Sailor',
    leadInitials: p.lead_initials || p.leadInitials || 'DS',
    territory: p.territory || 'DS / TERRITORY 014',
    coord: p.coord || '—',
    scope: p.scope || 'Nenhum escopo definido.',
    revisionsTotal: p.revisions_total || 0,
    revisionsUsed: p.revisions_used || 0,
    clientName: p.client_name || p.clientName || 'Cliente',
    deliverables: (p.deliverables || []).map(d => ({
      ...d,
      primary: !!d.primary_deliverable,
      n: d.n || '01',
      name: d.name || 'Entregável',
      status: d.status || 'idle',
      statusLabel: d.status_label || d.statusLabel || 'Aguardando',
      deadline: d.deadline || '—',
      versions: d.versions || 0,
      current: d.current || '—'
    })),
    activity: (p.activity || []).map(a => ({
      ...a,
      txt: a.txt || '',
      who: a.who || '',
      when_text: a.when_text || a.when || ''
    })),
    conversation: p.conversation || [],
    finalFiles: p.finalFiles || []
  };
}

function mapDbBriefing(b) {
  if (!b) return b;
  let parsedData = {};
  if (b.briefing_data) {
    if (typeof b.briefing_data === 'string') {
      try {
        parsedData = JSON.parse(b.briefing_data);
      } catch (e) {
        console.error('Erro ao fazer parse do briefing_data', e);
      }
    } else {
      parsedData = b.briefing_data;
    }
  }
  return {
    id: b.id,
    client: b.client_name || b.client,
    client_id: b.client_id,
    project: b.project_name || b.project,
    service: b.service,
    received: b.received,
    receivedShort: b.received_short || b.receivedShort,
    attachments: b.attachments,
    status: b.status,
    statusLabel: b.status_label || b.statusLabel,
    priority: b.priority,
    blocks: parsedData.blocks || b.blocks || [],
    files: parsedData.files || b.files || [],
    external_files_link: b.external_files_link || parsedData.external_files_link || ''
  };
}

window.DATA = {
  async refreshProjects() {
    try {
      const projs = await API.getProjects();
      const mapped = projs.map(p => mapDbProject(p));
      window.DS_DATA._projects = mapped;
      window.DS_DATA.clientProjects = mapped;
    } catch (e) {
      console.warn('API unavailable, using mock project data', e);
    }
  },

  async refreshClients() {
    try {
      const clientsData = await API.getClients();
      window.DS_DATA._clients = clientsData;
      window.DS_DATA.clients = clientsData;
    } catch (e) {
      console.warn('API unavailable, using mock client data');
    }
  },

  async refreshBriefings() {
    try {
      const briefs = await API.getBriefings();
      const mapped = briefs.map(b => mapDbBriefing(b));
      window.DS_DATA._briefings = mapped;
      window.DS_DATA.briefingsInbox = mapped;
    } catch (e) {
      console.warn('API unavailable, using mock briefing data');
    }
  },

  async refreshAgenda() {
    try {
      const agendaData = await API.getAgenda();
      window.DS_DATA._agenda = agendaData;
      window.DS_DATA.agenda = agendaData;
    } catch (e) {
      console.warn('API unavailable, using mock agenda data');
    }
  },

  async refreshAdminProjects() {
    try {
      const projs = await API.getAdminProjects();
      const mapped = projs.map(p => ({
        id: p.id,
        name: p.name,
        client: p.client,
        service: p.service,
        status: p.status,
        statusLabel: p.statusLabel,
        deadline: p.deadline,
        lead: p.lead,
        leadInitials: p.leadInitials,
        priority: p.priority || 'med'
      }));
      window.DS_DATA._adminProjects = mapped;
      window.DS_DATA.adminProjects = mapped;
    } catch (e) {
      console.warn('API unavailable, using mock admin project data');
    }
  },

  async refreshStats() {
    try {
      const stats = await API.getStats();
      window.DS_DATA._stats = stats;
      window.DS_DATA.adminStats = [
        { l: 'Projetos ativos', v: String(stats.projectsActive), desc: `${String(stats.overdue).padStart(2, '0')} acima do prazo planejado` },
        { l: 'Briefings na fila', v: String(stats.briefingsPending), desc: 'Fila de análise em tempo real' },
        { l: 'Aprovações pendentes', v: String(stats.approvalsPending), desc: 'Aguardando ação do cliente' },
        { l: 'Revisões em curso', v: String(stats.revisionsOpen), desc: 'Ajustes solicitados' },
        { l: 'Entregas nesta semana', v: String(stats.deliveriesWeek), desc: 'Cronograma da semana atual' },
        { l: 'Em atraso', v: String(stats.overdue), desc: 'Atenção necessária' }
      ];

      const clientProjs = window.DS_DATA.clientProjects || [];
      const activeCount = clientProjs.filter(p => p.status !== 'done' && p.status !== 'archived').length;
      let approvals = 0;
      let inProduction = 0;
      let finalFilesCount = 0;
      let dynamicNextMoves = [];

      const projIds = clientProjs.map(p => p.id);
      if (projIds.length > 0) {
        try {
          const clientData = await API.getClientDashboardData(projIds);
          const deliverables = clientData.deliverables || [];
          const finalFiles = clientData.finalFiles || [];

          approvals = deliverables.filter(d => d.status === 'waiting').length;
          inProduction = deliverables.filter(d => d.status === 'production').length;
          finalFilesCount = finalFiles.length;

          // Build dynamic nextMoves for the timeline
          const activeDeliverables = deliverables
            .filter(d => ['waiting', 'review', 'production'].includes(d.status))
            .sort((a, b) => {
              const dateA = a.deadline ? new Date(a.deadline.replace(/(\d+)\s+([a-z]+)/i, '$1 $2')) : new Date(8640000000000000);
              const dateB = b.deadline ? new Date(b.deadline.replace(/(\d+)\s+([a-z]+)/i, '$1 $2')) : new Date(8640000000000000);
              return dateA - dateB;
            });

          dynamicNextMoves = activeDeliverables.map(d => {
            let day = '—';
            let month = 'PRAZO';
            if (d.deadline) {
              const parts = d.deadline.trim().split(/\s+/);
              if (parts.length >= 2) {
                day = parts[0];
                month = parts[1].toUpperCase();
              } else {
                day = d.deadline;
              }
            }
            return {
              day,
              month,
              urgent: d.status === 'waiting',
              ttl: React.createElement(React.Fragment, null, d.status === 'waiting' ? 'Aprovar ' : d.status === 'review' ? 'Revisar ' : 'Desenvolver ', React.createElement('em', null, d.name)),
              meta: [d.status_label || 'Status', (d.projects && d.projects.title) || 'Projeto'],
              action: {
                label: d.status === 'waiting' ? 'Revisar' : 'Abrir',
                target: `project-${d.project_id}`
              }
            };
          });
        } catch (dbErr) {
          console.warn('Could not fetch client real deliverables, using project schema', dbErr);
          clientProjs.forEach(p => {
            approvals += (p.deliverables || []).filter(d => d.status === 'waiting').length;
            inProduction += (p.deliverables || []).filter(d => d.status === 'production').length;
            finalFilesCount += (p.finalFiles || []).length;
          });
        }
      }

      window.DS_DATA.clientStats = [
        { l: 'Projetos ativos', v: String(activeCount), desc: clientProjs.map(p => p.service).join(' · ') || 'Nenhum em curso' },
        { l: 'Aprovação pendente', v: String(approvals), desc: approvals > 0 ? 'Ação requerida no portal' : 'Tudo em dia' },
        { l: 'Em produção', v: String(inProduction), desc: 'Desenvolvimento ativo' },
        { l: 'Arquivos finais', v: String(finalFilesCount), desc: 'Disponíveis para download' }
      ];

      window.DS_DATA.nextMoves = dynamicNextMoves;
    } catch (e) {
      console.warn('API unavailable, using mock stats', e);
    }
  },

  async refreshAll() {
    await Promise.all([
      this.refreshProjects(),
      this.refreshClients(),
      this.refreshBriefings(),
      this.refreshAgenda(),
      this.refreshAdminProjects(),
      this.refreshStats()
    ]);
  },

  get projects() {
    return window.DS_DATA._projects || window.DS_DATA.clientProjects;
  },

  get adminProjects() {
    return window.DS_DATA._adminProjects || window.DS_DATA.adminProjects;
  },

  get briefings() {
    return window.DS_DATA._briefings || window.DS_DATA.briefingsInbox;
  },

  get agenda() {
    return window.DS_DATA._agenda || window.DS_DATA.agenda;
  },

  get stats() {
    return window.DS_DATA._stats || window.DS_DATA.adminStats;
  },

  get clients() {
    return window.DS_DATA._clients || window.DS_DATA.clients;
  },

  async getProject(id) {
    try {
      const p = await API.getProject(id);
      const mapped = mapDbProject(p);
      if (window.DS_DATA.clientProjects) {
        window.DS_DATA.clientProjects = window.DS_DATA.clientProjects.map(x => x.id === id ? mapped : x);
      }
      return mapped;
    } catch (e) {
      const fallback = window.DS_DATA.clientProjects.find(x => x.id === id);
      return mapDbProject(fallback);
    }
  },

  async getBriefing(id) {
    try {
      const b = await API.getBriefing(id);
      return mapDbBriefing(b);
    } catch (e) {
      const fallback = window.DS_DATA.briefingLume;
      return mapDbBriefing(fallback);
    }
  },

  async getClient(id) {
    try {
      return await API.getClient(id);
    } catch (e) {
      return window.DS_DATA.clients.find(x => x.id === id);
    }
  },

  get currentUser() {
    return window.DS_DATA._currentUser || window.DS_DATA.currentClient;
  },

  set currentUser(u) {
    window.DS_DATA._currentUser = u;
  }
};