import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { createServer } from 'http';
import { Server } from 'socket.io';
import { initDatabase, db } from './db.js';
import authRoutes from './routes/auth.js';
import signalsRoutes from './routes/signals.js';
import dashboardRoutes from './routes/dashboard.js';
import paymentsRoutes from './routes/payments.js';
import cooperationRoutes from './routes/cooperation.js';
import supportRoutes from './routes/support.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const isProd = process.env.NODE_ENV === 'production';
const frontendDist = path.join(__dirname, '..', '..', 'frontend', 'dist');

await initDatabase();

const allowedOrigins = [
  'http://localhost:5173',
  'http://127.0.0.1:5173',
  process.env.FRONTEND_URL,
  process.env.APP_URL,
  'https://online.rayanasr.com',
].filter(Boolean);

function corsOrigin(origin, callback) {
  if (!origin || allowedOrigins.includes(origin)) callback(null, true);
  else if (isProd && process.env.APP_URL && origin === process.env.APP_URL) callback(null, true);
  else callback(null, false);
}

const app = express();
if (isProd) app.set('trust proxy', 1);

const httpServer = createServer(app);
const io = new Server(httpServer, {
  path: '/socket.io/',
  cors: {
    origin: allowedOrigins,
    methods: ['GET', 'POST'],
  },
  transports: ['polling', 'websocket'],
});

app.use(cors({ origin: corsOrigin, credentials: true }));
app.use(express.json());
app.use('/uploads', express.static(path.join(__dirname, '..', 'uploads')));

app.get('/api/health', (req, res) =>
  res.json({ ok: true, service: 'SignalPro API', env: isProd ? 'production' : 'development' })
);
app.use('/api/auth', authRoutes);
app.use('/api/signals', signalsRoutes);
app.use('/api/dashboard', dashboardRoutes);
app.use('/api/payments', paymentsRoutes);
app.use('/api/cooperation', cooperationRoutes);
app.use('/api/support', supportRoutes);

if (isProd && fs.existsSync(frontendDist)) {
  app.use(express.static(frontendDist, { maxAge: '1d' }));
  app.get('*', (req, res, next) => {
    if (
      req.path.startsWith('/api') ||
      req.path.startsWith('/uploads') ||
      req.path.startsWith('/socket.io')
    ) {
      return next();
    }
    res.sendFile(path.join(frontendDist, 'index.html'));
  });
}

function broadcastSignalUpdate() {
  const active = db.prepare(`SELECT COUNT(*) as c FROM signals WHERE status = 'active'`).get().c;
  const since = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
  const recentlyClosed = db
    .prepare(`SELECT COUNT(*) as c FROM signals WHERE status = 'closed' AND closed_at >= ?`)
    .get(since).c;
  const lastUpdate = db.prepare(`SELECT MAX(last_update_at) as t FROM signals`).get().t;
  io.emit('signals:update', { active, recentlyClosed, lastUpdate, at: new Date().toISOString() });
}

io.on('connection', (socket) => {
  socket.emit('signals:update', { connected: true });
});

setInterval(() => {
  const updated = db
    .prepare(`
    UPDATE signals SET last_update_at = datetime('now')
    WHERE status = 'active' AND id = (
      SELECT id FROM signals WHERE status = 'active' ORDER BY RANDOM() LIMIT 1
    )
  `)
    .run();
  if (updated.changes > 0) broadcastSignalUpdate();
}, 30000);

const PORT = process.env.PORT || 3001;
const HOST = isProd ? '0.0.0.0' : '127.0.0.1';

httpServer.listen(PORT, HOST, () => {
  console.log(`SignalPro running on ${HOST}:${PORT} (${isProd ? 'production' : 'development'})`);
  if (isProd && !fs.existsSync(frontendDist)) {
    console.warn('WARNING: frontend/dist not found. Run: npm run build');
  }
});

export { io, broadcastSignalUpdate };
