const express = require('express');
const cors = require('cors');
const { Pool } = require('pg');
const { createClient } = require('redis');
const cookieParser = require('cookie-parser');
const fs = require('fs');
const path = require('path');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 4001;

const allowedOrigins = [
  'http://localhost:4000',
  'https://qr.houseofwebsites.ai',
  process.env.FRONTEND_URL
].filter(Boolean);

app.use(cors({ origin: allowedOrigins, credentials: true }));
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));
app.use(cookieParser());

// Routes
const authRoutes = require('./routes/auth');
const qrRoutes = require('./routes/qr');
const redirectRoutes = require('./routes/redirect');
const analyticsRoutes = require('./routes/analytics');
const adminRoutes = require('./routes/admin');
const paymentsRoutes = require('./routes/payments');
const foldersRoutes = require('./routes/folders');

app.use('/api/auth', authRoutes);
app.use('/api/qr', qrRoutes);
app.use('/api/analytics', analyticsRoutes);
app.use('/api/admin', adminRoutes);
app.use('/api/payments', paymentsRoutes);
app.use('/api/folders', foldersRoutes);

// Support Traefik stripped prefixes
app.use('/auth', authRoutes);
app.use('/qr', qrRoutes);
app.use('/analytics', analyticsRoutes);
app.use('/admin', adminRoutes);
app.use('/payments', paymentsRoutes);
app.use('/folders', foldersRoutes);

app.use('/l', redirectRoutes);

// Postgres setup
const pgPool = new Pool({
  host: process.env.PGHOST || 'postgres',
  port: process.env.PGPORT || 5432,
  user: process.env.PGUSER || 'postgres',
  password: process.env.PGPASSWORD || 'postgres',
  database: process.env.PGDATABASE || 'ckqr',
});

// Initialize Database automatically
const initDb = async () => {
  try {
    const sql = fs.readFileSync(path.join(__dirname, 'db', 'init.sql'), 'utf8');
    await pgPool.query(sql);
    console.log('Database initialized successfully.');
    
    // Force promote the owner to admin (enterprise role)
    await pgPool.query("UPDATE users SET role = 'enterprise', is_email_verified = true WHERE email = 'mohan.k@cavininfotech.com'");
    await pgPool.query("UPDATE users SET role = 'enterprise', is_email_verified = true WHERE email = 'admin@cavininfotech.com'");
    await pgPool.query("UPDATE users SET role = 'enterprise', is_email_verified = true WHERE role = 'admin'");
  } catch (err) {
    console.error('Database initialization failed:', err);
  }
};
initDb();

// Redis setup
const redisClient = createClient({
  url: `redis://${process.env.REDIS_HOST || 'redis'}:${process.env.REDIS_PORT || 6379}`
});

redisClient.on('error', (err) => console.log('Redis Client Error', err));

const healthCheck = async (req, res) => {
  let pgStatus = 'Unknown';
  let redisStatus = 'Unknown';

  try {
    const pgRes = await pgPool.query('SELECT NOW()');
    pgStatus = 'Connected';
  } catch (err) {
    pgStatus = `Error: ${err.message}`;
  }

  try {
    if (!redisClient.isOpen) {
      await redisClient.connect();
    }
    await redisClient.ping();
    redisStatus = 'Connected';
  } catch (err) {
    redisStatus = `Error: ${err.message}`;
  }

  res.json({
    status: 'ok',
    services: {
      api: 'Running',
      postgres: pgStatus,
      redis: redisStatus
    }
  });
};

app.get('/api/health', healthCheck);
app.get('/health', healthCheck);

// Auto-migrate schema
pgPool.query(`
CREATE TABLE IF NOT EXISTS folders (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);`).catch(console.error);

pgPool.query(`ALTER TABLE qr_codes ADD COLUMN IF NOT EXISTS name VARCHAR(255);`).catch(console.error);
pgPool.query(`ALTER TABLE qr_codes ADD COLUMN IF NOT EXISTS folder_id UUID REFERENCES folders(id) ON DELETE SET NULL;`).catch(console.error);
pgPool.query(`
CREATE TABLE IF NOT EXISTS qr_scans (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    qr_code_id UUID REFERENCES qr_codes(id) ON DELETE CASCADE,
    ip_address VARCHAR(45),
    user_agent TEXT,
    os VARCHAR(50),
    device_type VARCHAR(50),
    browser VARCHAR(50),
    country VARCHAR(100),
    city VARCHAR(100),
    scanned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);`).catch(console.error);

pgPool.query(`
ALTER TABLE users 
ADD COLUMN IF NOT EXISTS is_email_verified BOOLEAN DEFAULT false,
ADD COLUMN IF NOT EXISTS email_verification_token VARCHAR(255);
`).catch(console.error);

pgPool.query(`ALTER TABLE qr_codes ADD COLUMN IF NOT EXISTS tags TEXT[] DEFAULT '{}';`).catch(console.error);
pgPool.query(`ALTER TABLE qr_codes ADD COLUMN IF NOT EXISTS routing_data JSONB;`).catch(console.error);
pgPool.query(`ALTER TABLE qr_codes ADD COLUMN IF NOT EXISTS workspace_id UUID;`).catch(console.error);
pgPool.query(`ALTER TABLE folders ADD COLUMN IF NOT EXISTS workspace_id UUID;`).catch(console.error);

pgPool.query(`
CREATE TABLE IF NOT EXISTS workspace_members (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    owner_id UUID REFERENCES users(id) ON DELETE CASCADE,
    member_email VARCHAR(255) NOT NULL,
    role VARCHAR(50) DEFAULT 'editor',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(owner_id, member_email)
);
`).catch(console.error);

pgPool.query(`
CREATE TABLE IF NOT EXISTS app_settings (
    key VARCHAR(100) PRIMARY KEY,
    value TEXT,
    category VARCHAR(50),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`).then(() => {
    return pgPool.query(`
        INSERT INTO app_settings (key, value, category) VALUES 
            ('icici_merchant_id', '', 'payments'),
            ('icici_api_key', '', 'payments'),
            ('google_safe_browsing_key', '', 'security'),
            ('google_client_id', '', 'auth'),
            ('apple_service_id', '', 'auth'),
            ('smtp_host', 'smtp.office365.com', 'smtp'),
            ('smtp_port', '587', 'smtp'),
            ('smtp_user', 'noreply@cavininfotech.com', 'smtp'),
            ('smtp_pass', 'xmkshjlszjbkcyzb', 'smtp'),
            ('smtp_secure', 'false', 'smtp')
        ON CONFLICT (key) DO NOTHING;
    `);
}).catch(console.error);

app.listen(port, () => {
  console.log(`CK-QR API listening on port ${port}`);
});
