// ============================================================
// Dashboard estadístico conectado al servidor
// ============================================================
const Dashboard = ({ onSessionExpired }) => {
  const [state, setState] = React.useState({ loading: true, error: '', data: null });

  const loadDashboard = React.useCallback(async () => {
    setState(previous => ({ ...previous, loading: true, error: '' }));
    try {
      const data = await window.dashboardService.getDashboard();
      setState({ loading: false, error: '', data });
    } catch (error) {
      if (error?.status === 401 && typeof onSessionExpired === 'function') {
        onSessionExpired();
        return;
      }
      setState({
        loading: false,
        error: error?.message || 'No fue posible cargar el dashboard.',
        data: null
      });
    }
  }, [onSessionExpired]);

  React.useEffect(() => {
    loadDashboard();
  }, [loadDashboard]);

  if (state.loading) {
    return (
      <div className="card">
        <div className="card-body empty-state">
          <div className="spinner"/>
          <div className="fw-600">Consultando datos reales del servidor…</div>
        </div>
      </div>
    );
  }

  if (state.error || !state.data) {
    return (
      <div className="card">
        <div className="card-body empty-state">
          <Icon name="alert" size={30}/>
          <div className="fw-600">No se pudo cargar el dashboard</div>
          <div className="text-sm text-2">{state.error}</div>
          <button className="btn btn-primary" onClick={loadDashboard}>Reintentar</button>
        </div>
      </div>
    );
  }

  const data = state.data;
  const summary = data.summary || {};
  const stages = data.stage_progress || data.stages || {};
  const statuses = data.statuses || {};
  const project = data.project || {};
  const total = Math.max(0, Number(summary.total_books) || 0);
  const metaBooks = Math.max(total, Number(APP_DATA?.PROYECTO?.metaLibros) || total || 1);
  const metaImages = Number(APP_DATA?.PROYECTO?.metaImagenes) || 70000;
  const finalized = Number(summary.finalized) || 0;
  const processedImages = Number(summary.processed_images) || 0;
  const endDate = project.end_date || APP_DATA?.PROYECTO?.deadline || null;
  const daysRemaining = endDate
    ? Math.max(0, Math.ceil((new Date(`${endDate}T23:59:59`) - new Date()) / 86400000))
    : null;
  const qualityTotal = (Number(statuses.approved) || 0) + (Number(statuses.rejected) || 0);
  const acceptanceRate = qualityTotal > 0
    ? ((Number(statuses.approved) || 0) / qualityTotal) * 100
    : 0;

  const daily = Array.isArray(data.daily) ? data.daily : [];
  const dailyMax = Math.max(1, ...daily.map(item => Number(item.digitalized) || 0));
  const productivity = Array.isArray(data.productivity) ? data.productivity : [];
  const pipeline = data.pipeline || {};

  // Proyección calculada con datos reales del servidor y la meta configurada del proyecto.
  const projectionStartDate = project.start_date || APP_DATA?.PROYECTO?.fechaInicio || null;
  const projectionEndDate = project.end_date || APP_DATA?.PROYECTO?.deadline || null;
  const projectionTarget = Math.max(total, Number(APP_DATA?.PROYECTO?.metaLibros) || total || 1);
  const todayAtMidnight = new Date();
  todayAtMidnight.setHours(0, 0, 0, 0);
  const startAtMidnight = projectionStartDate ? new Date(`${projectionStartDate}T00:00:00`) : null;
  const endAtMidnight = projectionEndDate ? new Date(`${projectionEndDate}T00:00:00`) : null;
  const hasValidProjectionDates = startAtMidnight instanceof Date && !Number.isNaN(startAtMidnight.getTime())
    && endAtMidnight instanceof Date && !Number.isNaN(endAtMidnight.getTime());
  const elapsedProjectionDays = hasValidProjectionDates
    ? Math.max(1, Math.floor((todayAtMidnight - startAtMidnight) / 86400000) + 1)
    : 1;
  const remainingProjectionDays = hasValidProjectionDates
    ? Math.max(0, Math.ceil((endAtMidnight - todayAtMidnight) / 86400000))
    : 0;
  const currentProjectionRate = finalized / elapsedProjectionDays;
  const missingProjectionBooks = Math.max(0, projectionTarget - finalized);
  const projectedBooksAtDeadline = Math.min(
    projectionTarget,
    Math.max(finalized, Math.round(finalized + (currentProjectionRate * remainingProjectionDays)))
  );
  const requiredProjectionRate = remainingProjectionDays > 0
    ? missingProjectionBooks / remainingProjectionDays
    : (missingProjectionBooks > 0 ? missingProjectionBooks : 0);
  const projectionOnTrack = missingProjectionBooks === 0 || projectedBooksAtDeadline >= projectionTarget;
  const projectionExpired = hasValidProjectionDates && remainingProjectionDays === 0 && missingProjectionBooks > 0;
  const deadlineLabel = hasValidProjectionDates
    ? endAtMidnight.toLocaleDateString('es-MX', { day: 'numeric', month: 'long' })
    : 'la fecha objetivo';

  const stageRows = [
    { key: 'catalog', label: 'Catálogo / pendientes', color: '#64748b' },
    { key: 'digitization', label: 'Digitalización', color: '#0f766e' },
    { key: 'editing', label: 'Edición', color: '#7e22ce' },
    { key: 'quality_control', label: 'Control de calidad', color: '#b45309' },
    { key: 'conversion', label: 'Conversión', color: '#1e40af' },
    { key: 'publication', label: 'Publicación / finalizados', color: '#15803d' },
  ];

  const stageLabel = (stage) => ({
    catalog: 'Catálogo', digitization: 'Digitalización', editing: 'Edición',
    quality_control: 'Control de calidad', conversion: 'Conversión',
    publication: 'Publicación', published: 'Publicado'
  }[stage] || stage || 'Sin etapa');

  const statusLabel = (status) => ({
    pending: 'Pendiente', assigned: 'Asignado', in_progress: 'En proceso',
    completed: 'Completado', approved: 'Aprobado', rejected: 'Rechazado',
    correction_required: 'Requiere corrección', cancelled: 'Cancelado'
  }[status] || status || 'Sin estado');

  return (
    <div className="stack dashboard-real">
      <div className="dashboard-source-row">
        <div>
          <div className="text-sm fw-600">{project.name || 'Proyecto de digitalización'}</div>
          <div className="text-xs text-3">Datos consultados directamente desde MySQL · actualización {new Date(data.generated_at).toLocaleString('es-MX')}</div>
        </div>
        <button className="btn btn-secondary" onClick={loadDashboard}>
          <Icon name="refresh" size={14}/> Actualizar
        </button>
      </div>

      <div className="kpi-grid">
        <KPI
          label="Libros en catálogo"
          value={fmtNum(total)}
          sub={`${fmtNum(Number(summary.total_pages) || 0)} páginas registradas`}
          progress={100}
          tone="primary"
        />
        <KPI
          label="Asignaciones activas"
          value={fmtNum((Number(summary.pending_assignments) || 0) + (Number(summary.active_assignments) || 0))}
          sub={`${fmtNum(Number(summary.pending_assignments) || 0)} pendientes · ${fmtNum(Number(summary.active_assignments) || 0)} en proceso`}
          progress={total > 0 ? (((Number(summary.pending_assignments) || 0) + (Number(summary.active_assignments) || 0)) / total) * 100 : 0}
          tone="amber"
        />
        <KPI
          label="Libros finalizados"
          value={`${fmtNum(finalized)} / ${fmtNum(metaBooks)}`}
          sub={`${metaBooks > 0 ? ((finalized / metaBooks) * 100).toFixed(1) : '0.0'}% de la meta`}
          progress={metaBooks > 0 ? (finalized / metaBooks) * 100 : 0}
          tone="success"
        />
        <KPI
          label="Imágenes procesadas"
          value={fmtNum(processedImages)}
          sub={processedImages > 0 ? `${((processedImages / metaImages) * 100).toFixed(1)}% de ${fmtNum(metaImages)}` : 'Se actualizará con la producción registrada'}
          progress={metaImages > 0 ? (processedImages / metaImages) * 100 : 0}
          tone="primary"
        />
      </div>

      <div className="card dashboard-projection-card">
        <div className="card-header">
          <Icon name="target" size={18}/>
          <div>
            <div className="card-title">Proyección al deadline</div>
            <div className="card-subtitle">¿Vamos a llegar al {deadlineLabel}?</div>
          </div>
        </div>
        <div className="card-body">
          <div className="dashboard-projection-grid">
            <div className="dashboard-projection-metric">
              <div className="dashboard-projection-label">PROYECCIÓN AL DEADLINE</div>
              <div className="dashboard-projection-value">{fmtNum(projectedBooksAtDeadline)} libros</div>
              <div className="dashboard-projection-subtext">
                al ritmo actual ({currentProjectionRate.toFixed(2)} libros/día)
              </div>
            </div>
            <div className="dashboard-projection-metric">
              <div className="dashboard-projection-label">RITMO NECESARIO</div>
              <div className="dashboard-projection-value">{requiredProjectionRate.toFixed(1)}</div>
              <div className="dashboard-projection-subtext">libros/día para llegar</div>
            </div>
          </div>

          <div className={`dashboard-projection-alert ${projectionExpired ? 'late' : projectionOnTrack ? 'ok' : 'warning'}`}>
            {projectionExpired ? (
              <>⚠ La fecha objetivo terminó y todavía faltan {fmtNum(missingProjectionBooks)} libros.</>
            ) : projectionOnTrack ? (
              <>✓ Va en línea: al ritmo actual se proyectan {fmtNum(projectedBooksAtDeadline)} libros para la fecha objetivo.</>
            ) : (
              <>⚠ Necesita acelerar: Faltan {fmtNum(missingProjectionBooks)} libros en {fmtNum(remainingProjectionDays)} días. Se requiere aumentar producción.</>
            )}
          </div>
        </div>
      </div>

      <div className="stat-grid grid-2">
        <div className="card">
          <div className="card-header">
            <Icon name="stats" size={16}/>
            <div>
              <div className="card-title">Avance acumulado por etapa</div>
              <div className="card-subtitle">Libros que han alcanzado cada etapa · datos reales de MySQL</div>
            </div>
          </div>
          <div className="card-body">
            <div className="stack" style={{ gap: 18 }}>
              {stageRows.map(item => {
                const value = Number(stages[item.key]) || 0;
                const pct = total > 0 ? (value / total) * 100 : 0;
                return (
                  <div key={item.key}>
                    <div className="row" style={{ marginBottom: 6 }}>
                      <span className="fw-600 text-sm">{item.label}</span>
                      <div className="spacer"/>
                      <span className="text-mono text-sm">{fmtNum(value)}</span>
                      <span className="text-sm text-2" style={{ width: 54, textAlign: 'right' }}>{pct.toFixed(1)}%</span>
                    </div>
                    <ProgressBar value={value} max={Math.max(1, total)} color={item.color}/>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <Icon name="target" size={16}/>
            <div>
              <div className="card-title">Indicadores operativos</div>
              <div className="card-subtitle">Calculados con libros, asignaciones e historial</div>
            </div>
          </div>
          <div className="card-body dashboard-indicators">
            <div className="dashboard-indicator blue">
              <span>Pendientes en catálogo</span>
              <strong>{fmtNum(Number(statuses.pending) || 0)}</strong>
            </div>
            <div className="dashboard-indicator amber">
              <span>En proceso</span>
              <strong>{fmtNum(Number(statuses.in_progress) || 0)}</strong>
            </div>
            <div className="dashboard-indicator green">
              <span>Completados</span>
              <strong>{fmtNum(Number(statuses.completed) || 0)}</strong>
            </div>
            <div className="dashboard-indicator red">
              <span>Rechazados / corrección</span>
              <strong>{fmtNum(Number(statuses.rejected) || 0)}</strong>
            </div>
            <div className="dashboard-indicator purple">
              <span>Tasa de aceptación CC</span>
              <strong>{acceptanceRate.toFixed(0)}%</strong>
            </div>
            <div className="dashboard-indicator neutral">
              <span>Días restantes</span>
              <strong>{daysRemaining === null ? '—' : daysRemaining}</strong>
            </div>
          </div>
        </div>
      </div>

      <div className="card">
        <div className="card-header">
          <Icon name="trending" size={16}/>
          <div>
            <div className="card-title">Producción real de los últimos 45 días</div>
            <div className="card-subtitle">Libros cuya digitalización fue completada y registrada en el historial</div>
          </div>
        </div>
        <div className="card-body">
          <div className="bar-chart dashboard-real-chart">
            {daily.map((item, index) => {
              const value = Number(item.digitalized) || 0;
              return (
                <div
                  key={item.date || index}
                  className={`bar-chart-item ${value === 0 ? 'zero' : ''}`}
                  style={{ height: `${Math.max(value === 0 ? 2 : 8, (value / dailyMax) * 100)}%` }}
                  data-tooltip={`${fmtDate(item.date)}: ${value} digitalizados · ${Number(item.edited) || 0} editados · ${Number(item.finalized) || 0} finalizados`}
                />
              );
            })}
          </div>
          <div className="row dashboard-chart-legend">
            <span>Hace 45 días</span>
            <span>Hoy</span>
          </div>
          {daily.every(item => Number(item.digitalized) === 0) && (
            <div className="dashboard-empty-note">Aún no hay eventos reales de digitalización completada durante este periodo.</div>
          )}
        </div>
      </div>

      <div className="stat-grid grid-2 dashboard-bottom-grid">
        <div className="card dashboard-productivity-card">
          <div className="card-header">
            <Icon name="users" size={16}/>
            <div>
              <div className="card-title">Productividad por usuario</div>
              <div className="card-subtitle">Libros trabajados en el periodo</div>
            </div>
          </div>
          <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
            <table className="data dashboard-productivity-table">
              <thead>
                <tr>
                  <th>Usuario</th>
                  <th style={{ textAlign: 'right' }}>Digitalizados</th>
                  <th style={{ textAlign: 'right' }}>Editados</th>
                  <th style={{ textAlign: 'right' }}>Imágenes</th>
                </tr>
              </thead>
              <tbody>
                {productivity.length === 0 ? (
                  <tr><td colSpan="4" className="text-center text-3">Aún no hay productividad real registrada.</td></tr>
                ) : productivity.map((user, index) => {
                  const initials = String(user.name || user.username || '?')
                    .split(/\s+/).filter(Boolean).slice(0, 2).map(part => part[0]).join('').toUpperCase();
                  const avatarColors = ['#4338ca', '#b45309', '#0f766e', '#1d4ed8', '#15803d', '#7e22ce', '#c2410c', '#be185d'];
                  return (
                    <tr key={user.user_id}>
                      <td>
                        <div className="row dashboard-user-cell">
                          <span className="avatar sm" style={{ background: avatarColors[index % avatarColors.length] }}>{initials}</span>
                          <span>{user.name}</span>
                        </div>
                      </td>
                      <td style={{ textAlign: 'right' }} className="text-mono">{Number(user.digitalized) ? fmtNum(user.digitalized) : '—'}</td>
                      <td style={{ textAlign: 'right' }} className="text-mono">{Number(user.edited) ? fmtNum(user.edited) : '—'}</td>
                      <td style={{ textAlign: 'right' }} className="text-mono">{fmtNum(Number(user.images) || 0)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>

        <div className="card dashboard-pipeline-card">
          <div className="card-header">
            <Icon name="alert" size={16}/>
            <div>
              <div className="card-title">Estado actual del pipeline</div>
              <div className="card-subtitle">Libros en cada etapa · datos reales de MySQL</div>
            </div>
          </div>
          <div className="card-body">
            <div className="stack dashboard-pipeline-list" style={{ gap: 8 }}>
              {[
                ['nuevo', 'Nuevo'],
                ['en_digitalizacion', 'En digitalización'],
                ['digitalizado', 'Digitalizado'],
                ['en_edicion', 'En edición'],
                ['editado', 'Editado'],
                ['en_cc', 'En control calidad'],
                ['aceptado', 'Aceptado'],
                ['rechazado', 'Rechazado'],
                ['en_conversion', 'En conversión'],
                ['finalizado', 'Finalizado']
              ].map(([key, label]) => {
                const count = Number(pipeline[key]) || 0;
                return (
                  <div key={key} className="dashboard-pipeline-row">
                    <StatusPill estatus={key}/>
                    <div className="spacer"/>
                    <span className="dashboard-pipeline-count">{fmtNum(count)}</span>
                    <span className="text-sm text-3">libro{count === 1 ? '' : 's'}</span>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>

    </div>
  );
};

Object.assign(window, { Dashboard });
