import express from "express";
import session from "express-session";
import { createServer } from "http";
import path from "path";
import { fileURLToPath } from "url";
import MemoryStore from "memorystore";

// Local database connection
import pkg from 'pg';
const { Pool } = pkg;
import { drizzle } from 'drizzle-orm/node-postgres';
import * as schema from "../shared/schema.js";
import { registerLocalRoutes } from "./routes.js";


// Set environment variables
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
process.env.PORT = process.env.PORT || '5000';
process.env.DATABASE_URL = process.env.DATABASE_URL || 'postgres://sam_app:it-105@127.0.0.1:5432/sam_db';
process.env.SESSION_SECRET = process.env.SESSION_SECRET || 'your-secret-key-change-in-production';
app.use(express.json({ limit: "10mb" }));
app.use(express.urlencoded({ extended: true, limit: "10mb" }));

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Database setup for local PostgreSQL
if (!process.env.DATABASE_URL) {
  throw new Error("DATABASE_URL must be set in .env file");
}

export const pool = new Pool({ 
  connectionString: process.env.DATABASE_URL,
  ssl: false // Local PostgreSQL doesn't need SSL
});

export const db = drizzle({ client: pool, schema });

// Create Express app
const app = express();
const port = parseInt(process.env.PORT || "5000");
const host = '0.0.0.0';

// CORS setup for local development
app.use((req, res, next) => {
  const allowedOrigins = [
    'http://localhost:5174',
    'http://127.0.0.1:5174',
    'http://0.0.0.0:5174',
    'http://192.168.10.27:5174'
  ];
  
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin || '') || !origin) {
    res.header('Access-Control-Allow-Origin', origin || '*');
  } else {
    res.header('Access-Control-Allow-Origin', '*');
  }
  
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

// Body parsing middleware
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ extended: true, limit: '50mb' }));

// Create session store
const MemoryStoreSession = MemoryStore(session);

// Session middleware
app.use(session({
  store: new MemoryStoreSession({
    checkPeriod: 86400000 // prune expired entries every 24h
  }),
  secret: process.env.SESSION_SECRET || 'your-secret-key-change-in-production',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: false, // Set to true in production with HTTPS
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}));

// Static file serving for uploads
app.use('/uploads', express.static(path.join(__dirname, '../uploads')));

// Register API routes
registerLocalRoutes(app, db);

// Serve static files from dist directory in production
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../client/dist')));
  
  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../client/dist/index.html'));
  });
}

// Error handling middleware
app.use((err: any, req: any, res: any, next: any) => {
  console.error('❌ Server error:', err);
  const status = err.status || err.statusCode || 500;
  const message = err.message || "Internal Server Error";
  
  res.status(status).json({ message });
});

// Test database connection
async function testDbConnection() {
  try {
    await pool.query('SELECT 1');
    console.log('✅ Database connection successful');
  } catch (error) {
    console.error('❌ Database connection failed:', error);
    console.error('Make sure PostgreSQL is running and DATABASE_URL is correct');
  }
}

// Start server
async function startServer() {
  try {
    await testDbConnection();
    
    const server = createServer(app);
    
    server.listen(port, host, () => {
      console.log(`✅ Persian Workflow System running on:`);
      console.log(`   📍 Local: http://localhost:${port}`);
      console.log(`   🌐 Network: http://${host}:${port}`);
      console.log(`   📊 Database: Connected to sam_db`);
      console.log(`   🔧 Environment: ${process.env.NODE_ENV}`);
    });
    
    // Backup server on port 4000 for frontend compatibility
    if (port !== 4000) {
      const backupApp = express();
      backupApp.use(express.json());
      
      backupApp.use('*', (req: any, res: any) => {
        const targetUrl = `http://127.0.0.1:${port}${req.originalUrl}`;
        console.log(`🔄 PROXY: ${req.method} ${req.originalUrl} -> port ${port}`);
        
        import('http').then(http => {
          const proxyReq = http.request({
            hostname: '127.0.0.1',
            port: port,
            path: req.originalUrl,
            method: req.method,
            headers: req.headers
          }, (proxyRes) => {
            res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
            proxyRes.pipe(res, { end: true });
          });
          
          proxyReq.on('error', (err) => {
            console.error('❌ Proxy error:', err.message);
            if (!res.headersSent) {
              res.status(500).json({ error: 'Proxy connection failed' });
            }
          });
          
          if (req.method !== 'GET' && req.method !== 'HEAD') {
            req.pipe(proxyReq, { end: true });
          } else {
            proxyReq.end();
          }
        });
      });
      
      const backupServer = createServer(backupApp);
      backupServer.listen(4000, '0.0.0.0', () => {
        console.log(`🔄 BACKUP proxy server running on 0.0.0.0:4000 -> ${port}`);
        console.log(`🌐 Network accessible at: http://192.168.10.27:4000`);
      });
    }
    
  } catch (error) {
    console.error('❌ Failed to start server:', error);
    process.exit(1);
  }
}

startServer();
