import { Router } from 'express'
import { v4 as uuidv4 } from 'uuid'
import { db } from '../config/database'
import { authenticate, authorize, AuthRequest } from '../middleware/auth'
import crypto from 'crypto'
import { syncScheduler } from '../services/syncScheduler'

const router = Router()

// Initialize network nodes table if not exists
db.exec(`
  CREATE TABLE IF NOT EXISTS network_nodes (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    location TEXT,
    ip_address TEXT NOT NULL,
    port INTEGER NOT NULL,
    api_key TEXT NOT NULL UNIQUE,
    type TEXT CHECK(type IN ('admin', 'local')) NOT NULL,
    is_online INTEGER DEFAULT 0,
    last_sync TEXT,
    last_ping TEXT,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL,
    created_by TEXT NOT NULL
  )
`)

// Initialize sync settings table
db.exec(`
  CREATE TABLE IF NOT EXISTS sync_settings (
    id TEXT PRIMARY KEY,
    auto_sync_interval TEXT,
    conflict_resolution TEXT CHECK(conflict_resolution IN ('admin', 'newest', 'manual')),
    sync_employees INTEGER DEFAULT 1,
    sync_skills INTEGER DEFAULT 1,
    sync_users INTEGER DEFAULT 1,
    sync_settings INTEGER DEFAULT 0,
    bandwidth_limit INTEGER,
    updated_at TEXT NOT NULL,
    updated_by TEXT NOT NULL
  )
`)

// Get all network nodes
router.get('/nodes', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const nodes = db.prepare(`
      SELECT * FROM network_nodes ORDER BY type DESC, name ASC
    `).all()

    res.json({ 
      success: true, 
      data: nodes.map((node: any) => ({
        id: node.id,
        name: node.name,
        location: node.location,
        ipAddress: node.ip_address,
        port: node.port,
        apiKey: node.api_key,
        type: node.type,
        isOnline: Boolean(node.is_online),
        lastSync: node.last_sync ? new Date(node.last_sync) : null,
        lastPing: node.last_ping ? new Date(node.last_ping) : null,
        createdAt: new Date(node.created_at),
        updatedAt: new Date(node.updated_at)
      }))
    })
  } catch (error) {
    next(error)
  }
})

// Create new network node
router.post('/nodes', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const { name, location, ipAddress, port, type } = req.body
    const nodeId = uuidv4()
    const apiKey = generateApiKey()
    const now = new Date().toISOString()

    db.prepare(`
      INSERT INTO network_nodes (
        id, name, location, ip_address, port, api_key, type,
        is_online, created_at, updated_at, created_by
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run(
      nodeId, name, location || null, ipAddress, port, apiKey, type,
      0, now, now, req.user!.id
    )

    res.status(201).json({
      success: true,
      data: {
        id: nodeId,
        apiKey: apiKey
      },
      message: 'Network node created successfully'
    })
  } catch (error) {
    next(error)
  }
})

// Update network node
router.put('/nodes/:id', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const { id } = req.params
    const { name, location, ipAddress, port } = req.body
    const now = new Date().toISOString()

    const result = db.prepare(`
      UPDATE network_nodes 
      SET name = ?, location = ?, ip_address = ?, port = ?, 
          updated_at = ?, updated_by = ?
      WHERE id = ?
    `).run(
      name, location || null, ipAddress, port,
      now, req.user!.id, id
    )

    if (result.changes === 0) {
      return res.status(404).json({
        success: false,
        error: { message: 'Network node not found' }
      })
    }

    res.json({
      success: true,
      message: 'Network node updated successfully'
    })
  } catch (error) {
    next(error)
  }
})

// Delete network node
router.delete('/nodes/:id', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const { id } = req.params

    const result = db.prepare('DELETE FROM network_nodes WHERE id = ?').run(id)

    if (result.changes === 0) {
      return res.status(404).json({
        success: false,
        error: { message: 'Network node not found' }
      })
    }

    res.json({
      success: true,
      message: 'Network node deleted successfully'
    })
  } catch (error) {
    next(error)
  }
})

// Ping network node
router.post('/nodes/:id/ping', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const { id } = req.params
    
    const node = db.prepare('SELECT * FROM network_nodes WHERE id = ?').get(id) as any
    
    if (!node) {
      return res.status(404).json({
        success: false,
        error: { message: 'Network node not found' }
      })
    }

    // TODO: Implement actual ping logic
    // For now, simulate ping
    const isOnline = Math.random() > 0.2 // 80% chance of being online
    const now = new Date().toISOString()

    db.prepare(`
      UPDATE network_nodes 
      SET is_online = ?, last_ping = ?
      WHERE id = ?
    `).run(isOnline ? 1 : 0, now, id)

    res.json({
      success: true,
      data: {
        isOnline,
        lastPing: now,
        responseTime: isOnline ? Math.floor(Math.random() * 100) + 10 : null
      }
    })
  } catch (error) {
    next(error)
  }
})

// Get sync settings
router.get('/sync-settings', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    let settings = db.prepare('SELECT * FROM sync_settings WHERE id = ?').get('default') as any

    if (!settings) {
      // Create default settings
      const now = new Date().toISOString()
      db.prepare(`
        INSERT INTO sync_settings (
          id, auto_sync_interval, conflict_resolution,
          sync_employees, sync_skills, sync_users, sync_settings,
          bandwidth_limit, updated_at, updated_by
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      `).run(
        'default', 'disabled', 'admin',
        1, 1, 1, 0,
        null, now, 'system'
      )

      settings = db.prepare('SELECT * FROM sync_settings WHERE id = ?').get('default') as any
    }

    res.json({
      success: true,
      data: {
        autoSyncInterval: settings.auto_sync_interval,
        conflictResolution: settings.conflict_resolution,
        syncEmployees: Boolean(settings.sync_employees),
        syncSkills: Boolean(settings.sync_skills),
        syncUsers: Boolean(settings.sync_users),
        syncSettings: Boolean(settings.sync_settings),
        bandwidthLimit: settings.bandwidth_limit
      }
    })
  } catch (error) {
    next(error)
  }
})

// Update sync settings
router.put('/sync-settings', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const {
      autoSyncInterval,
      conflictResolution,
      syncEmployees,
      syncSkills,
      syncUsers,
      syncSettings,
      bandwidthLimit
    } = req.body

    const now = new Date().toISOString()

    db.prepare(`
      UPDATE sync_settings 
      SET auto_sync_interval = ?, conflict_resolution = ?,
          sync_employees = ?, sync_skills = ?, sync_users = ?, sync_settings = ?,
          bandwidth_limit = ?, updated_at = ?, updated_by = ?
      WHERE id = ?
    `).run(
      autoSyncInterval,
      conflictResolution,
      syncEmployees ? 1 : 0,
      syncSkills ? 1 : 0,
      syncUsers ? 1 : 0,
      syncSettings ? 1 : 0,
      bandwidthLimit || null,
      now,
      req.user!.id,
      'default'
    )

    res.json({
      success: true,
      message: 'Sync settings updated successfully'
    })
  } catch (error) {
    next(error)
  }
})

// Trigger manual sync
router.post('/sync/trigger', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const { nodeIds } = req.body

    // TODO: Implement actual sync logic
    // For now, simulate sync process
    const now = new Date().toISOString()

    if (nodeIds && nodeIds.length > 0) {
      // Update specific nodes
      const placeholders = nodeIds.map(() => '?').join(',')
      db.prepare(`
        UPDATE network_nodes 
        SET last_sync = ?
        WHERE id IN (${placeholders})
      `).run(now, ...nodeIds)
    } else {
      // Update all nodes
      db.prepare(`
        UPDATE network_nodes 
        SET last_sync = ?
      `).run(now)
    }

    res.json({
      success: true,
      message: 'Sync triggered successfully',
      data: {
        syncedAt: now,
        nodeCount: nodeIds?.length || 'all'
      }
    })
  } catch (error) {
    next(error)
  }
})

// Get sync scheduler status
router.get('/sync-status', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
  try {
    const status = syncScheduler.getStatus()
    
    res.json({
      success: true,
      data: status
    })
  } catch (error) {
    next(error)
  }
})

function generateApiKey(): string {
  return crypto.randomBytes(32).toString('hex')
}

export default router