import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { mysqlTable, timestamp, text, int, boolean, varchar } from 'drizzle-orm/mysql-core';
import { sql } from 'drizzle-orm';

const devices = mysqlTable("devices", {
  id: int("id").primaryKey().autoincrement(),
  deviceId: varchar("device_id", { length: 255 }).notNull().unique(),
  name: varchar("name", { length: 255 }).notNull(),
  model: varchar("model", { length: 255 }),
  androidVersion: varchar("android_version", { length: 50 }),
  // OS version (Android or iOS)
  pairingToken: varchar("pairing_token", { length: 255 }),
  isConnected: boolean("is_connected").default(false),
  lastSeen: timestamp("last_seen"),
  storageTotal: int("storage_total"),
  // in GB
  storageUsed: int("storage_used"),
  // in GB
  // Encryption key storage (encrypted with master key)
  encryptionKey: text("encryption_key"),
  // Base64 encoded encrypted key
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow()
});
const adminUsers = mysqlTable("admin_users", {
  id: int("id").primaryKey().autoincrement(),
  username: varchar("username", { length: 255 }).notNull().unique(),
  email: varchar("email", { length: 255 }).notNull().unique(),
  passwordHash: varchar("password_hash", { length: 255 }).notNull(),
  fullName: varchar("full_name", { length: 255 }),
  role: varchar("role", { length: 50 }).default("admin"),
  isActive: boolean("is_active").default(true),
  lastLogin: timestamp("last_login"),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow()
});
const sessions = mysqlTable("sessions", {
  id: int("id").primaryKey().autoincrement(),
  sessionToken: varchar("session_token", { length: 255 }).notNull().unique(),
  userId: int("user_id").notNull(),
  expiresAt: timestamp("expires_at").notNull(),
  createdAt: timestamp("created_at").defaultNow()
});
const backups = mysqlTable("backups", {
  id: int("id").primaryKey().autoincrement(),
  deviceId: varchar("device_id", { length: 255 }).notNull(),
  backupId: varchar("backup_id", { length: 255 }).notNull().unique(),
  backupType: varchar("backup_type", { length: 50 }).notNull(),
  // 'full' or 'incremental'
  status: varchar("status", { length: 50 }).notNull(),
  // 'pending', 'in_progress', 'completed', 'failed'
  size: int("size"),
  // Size in MB
  filePath: varchar("file_path", { length: 500 }),
  metadata: text("metadata"),
  // JSON string for additional backup info
  // Encryption fields
  encrypted: boolean("encrypted").default(false),
  encryptionAlgorithm: varchar("encryption_algorithm", { length: 50 }),
  // 'aes-256-gcm'
  encryptionIv: varchar("encryption_iv", { length: 255 }),
  // Base64 encoded IV
  encryptionAuthTag: varchar("encryption_auth_tag", { length: 255 }),
  // Base64 encoded auth tag
  encryptionSalt: varchar("encryption_salt", { length: 255 }),
  // Base64 encoded salt (for password-based)
  // Compression fields
  compressed: boolean("compressed").default(false),
  compressionAlgorithm: varchar("compression_algorithm", { length: 50 }),
  // 'gzip'
  originalSize: int("original_size"),
  // Size before compression in bytes
  compressedSize: int("compressed_size"),
  // Size after compression in bytes
  compressionRatio: int("compression_ratio"),
  // Percentage saved (0-100)
  // Verification fields
  hash: varchar("hash", { length: 64 }),
  // SHA-256 hash (hex)
  checksum: varchar("checksum", { length: 8 }),
  // CRC32 checksum (hex)
  verified: boolean("verified").default(false),
  verifiedAt: timestamp("verified_at"),
  startedAt: timestamp("started_at"),
  completedAt: timestamp("completed_at"),
  errorMessage: text("error_message"),
  createdAt: timestamp("created_at").defaultNow()
});
const servers = mysqlTable("servers", {
  id: int("id").primaryKey().autoincrement(),
  serverId: varchar("server_id", { length: 255 }).notNull().unique(),
  name: varchar("name", { length: 255 }).notNull(),
  type: varchar("type", { length: 50 }).notNull(),
  // 'pc' or 'cloud'
  ipAddress: varchar("ip_address", { length: 45 }),
  // IPv4 or IPv6
  port: int("port").default(8080),
  apiKey: varchar("api_key", { length: 255 }),
  status: varchar("status", { length: 50 }).default("offline"),
  // 'online', 'offline', 'error'
  storageTotal: int("storage_total"),
  // in GB
  storageUsed: int("storage_used"),
  // in GB
  storageAllocated: int("storage_allocated"),
  // in GB
  lastPing: timestamp("last_ping"),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow()
});
const communicationLogs = mysqlTable("communication_logs", {
  id: int("id").primaryKey().autoincrement(),
  messageId: varchar("message_id", { length: 255 }).notNull().unique(),
  fromType: varchar("from_type", { length: 50 }).notNull(),
  // 'device', 'server', 'dashboard'
  fromId: varchar("from_id", { length: 255 }).notNull(),
  // deviceId or serverId
  toType: varchar("to_type", { length: 50 }).notNull(),
  // 'device', 'server', 'dashboard'
  toId: varchar("to_id", { length: 255 }),
  // deviceId or serverId (null for broadcast)
  messageType: varchar("message_type", { length: 50 }).notNull(),
  // 'status', 'command', 'notification', 'data'
  subject: varchar("subject", { length: 255 }),
  body: text("body"),
  metadata: text("metadata"),
  // JSON string for additional data
  status: varchar("status", { length: 50 }).default("sent"),
  // 'sent', 'delivered', 'read', 'failed'
  createdAt: timestamp("created_at").defaultNow()
});
const remoteCommands = mysqlTable("remote_commands", {
  id: int("id").primaryKey().autoincrement(),
  commandId: varchar("command_id", { length: 255 }).notNull().unique(),
  deviceId: varchar("device_id", { length: 255 }).notNull(),
  commandType: varchar("command_type", { length: 50 }).notNull(),
  // 'backup_now', 'pause', 'resume', 'cancel', 'settings_update'
  parameters: text("parameters"),
  // JSON string for command parameters
  status: varchar("status", { length: 50 }).default("pending"),
  // 'pending', 'sent', 'acknowledged', 'completed', 'failed'
  result: text("result"),
  // JSON string for command result
  sentAt: timestamp("sent_at").defaultNow(),
  acknowledgedAt: timestamp("acknowledged_at"),
  completedAt: timestamp("completed_at")
});
const storageConfig = mysqlTable("storage_config", {
  id: int("id").primaryKey().autoincrement(),
  storageType: varchar("storage_type", { length: 50 }).notNull().default("local"),
  // 'local', 's3', 'gcs', 'azure'
  config: text("config").notNull(),
  // JSON string with provider-specific configuration
  isActive: boolean("is_active").default(true),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow()
});
const backupSchedules = mysqlTable("backup_schedules", {
  id: int("id").primaryKey().autoincrement(),
  scheduleId: varchar("schedule_id", { length: 255 }).notNull().unique(),
  deviceId: varchar("device_id", { length: 255 }).notNull(),
  scheduleName: varchar("schedule_name", { length: 255 }).notNull(),
  frequency: varchar("frequency", { length: 50 }).notNull(),
  // 'daily', 'weekly', 'monthly', 'custom'
  timeOfDay: varchar("time_of_day", { length: 10 }),
  // HH:MM format (24-hour)
  daysOfWeek: text("days_of_week"),
  // JSON array [0-6] for weekly schedules (0=Sunday)
  dayOfMonth: int("day_of_month"),
  // 1-31 for monthly schedules
  customCron: varchar("custom_cron", { length: 255 }),
  // Cron expression for custom schedules
  backupType: varchar("backup_type", { length: 50 }).default("full"),
  // 'full' or 'incremental'
  enabled: boolean("enabled").default(true),
  conditions: text("conditions"),
  // JSON: { wifiOnly: true, minBattery: 20, charging: false }
  lastRun: timestamp("last_run"),
  nextRun: timestamp("next_run"),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow()
});
const uploadProgress = mysqlTable("upload_progress", {
  id: int("id").primaryKey().autoincrement(),
  backupId: varchar("backup_id", { length: 255 }).notNull().unique(),
  deviceId: varchar("device_id", { length: 255 }).notNull(),
  fileName: varchar("file_name", { length: 500 }).notNull(),
  totalChunks: int("total_chunks").notNull(),
  uploadedChunks: int("uploaded_chunks").default(0),
  totalSize: int("total_size"),
  // Total file size in bytes
  uploadedSize: int("uploaded_size").default(0),
  // Uploaded size in bytes
  status: varchar("status", { length: 50 }).default("uploading"),
  // 'uploading', 'completed', 'failed'
  startedAt: timestamp("started_at").defaultNow(),
  completedAt: timestamp("completed_at"),
  updatedAt: timestamp("updated_at").defaultNow()
});

const schema = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
  __proto__: null,
  adminUsers,
  backupSchedules,
  backups,
  communicationLogs,
  devices,
  remoteCommands,
  servers,
  sessions,
  storageConfig,
  uploadProgress
}, Symbol.toStringTag, { value: 'Module' }));

const envPath = join(process.cwd(), ".env");
if (existsSync(envPath)) {
  const envContent = readFileSync(envPath, "utf-8");
  envContent.split("\n").forEach((line) => {
    const match = line.match(/^([^=:#]+)=(.*)$/);
    if (match) {
      const key = match[1].trim();
      const value = match[2].trim().replace(/^["']|["']$/g, "");
      if (!process.env[key]) {
        process.env[key] = value;
      }
    }
  });
  console.log("[DB Client] Loaded environment from .env file");
  console.log("[DB Client] DB_HOST:", process.env.DB_HOST || "(not set)");
  console.log("[DB Client] DB_USER:", process.env.DB_USER || "(not set)");
  console.log("[DB Client] DB_NAME:", process.env.DB_NAME || "(not set)");
}
function getDatabaseConfig() {
  if (process.env.DB_HOST && process.env.DB_USER && process.env.DB_NAME && "DB_PASSWORD" in process.env) {
    return {
      host: process.env.DB_HOST,
      port: parseInt(process.env.DB_PORT || "3306"),
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME
    };
  }
  const configPath = "/alloc/config.json";
  if (!existsSync(configPath)) {
    throw new Error(
      "Database configuration not found. Please set environment variables (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) or ensure /alloc/config.json exists."
    );
  }
  try {
    const config = JSON.parse(readFileSync(configPath, "utf-8"));
    if (!config.DATABASE?.VALUE) {
      throw new Error("Invalid config.json structure: DATABASE.VALUE not found");
    }
    const db2 = config.DATABASE.VALUE;
    if (!db2.HOST || !db2.PORT || !db2.USERNAME || !db2.PASSWORD || !db2.NAME) {
      throw new Error("Invalid config.json: Missing required database credentials");
    }
    return {
      host: db2.HOST,
      port: db2.PORT,
      user: db2.USERNAME,
      password: db2.PASSWORD,
      database: db2.NAME
    };
  } catch (error) {
    if (error instanceof SyntaxError) {
      throw new Error(`Failed to parse ${configPath}: Invalid JSON format`);
    }
    throw error;
  }
}
let poolConnection = null;
let dbInstance = null;
function initializeConnection() {
  if (poolConnection) return;
  const dbConfig = getDatabaseConfig();
  poolConnection = mysql.createPool({
    host: dbConfig.host,
    port: dbConfig.port,
    user: dbConfig.user,
    password: dbConfig.password,
    database: dbConfig.database,
    ssl: {
      rejectUnauthorized: false
    },
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
  });
  dbInstance = drizzle(poolConnection, { schema, mode: "default" });
}
const db = new Proxy({}, {
  get(target, prop) {
    initializeConnection();
    return dbInstance[prop];
  }
});
async function closeConnection() {
  if (poolConnection) {
    await poolConnection.end();
  }
}

async function handler(req, res) {
  try {
    await db.execute(sql`
      CREATE TABLE IF NOT EXISTS upload_progress (
        id INT AUTO_INCREMENT NOT NULL,
        backup_id VARCHAR(255) NOT NULL,
        device_id VARCHAR(255) NOT NULL,
        file_name VARCHAR(500) NOT NULL,
        total_chunks INT NOT NULL,
        uploaded_chunks INT DEFAULT 0,
        total_size INT,
        uploaded_size INT DEFAULT 0,
        status VARCHAR(50) DEFAULT 'uploading',
        started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        completed_at TIMESTAMP NULL,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        CONSTRAINT upload_progress_id PRIMARY KEY (id),
        CONSTRAINT upload_progress_backup_id_unique UNIQUE (backup_id)
      )
    `);
    res.json({
      success: true,
      message: "upload_progress table created successfully"
    });
  } catch (error) {
    console.error("Failed to create table:", error);
    res.status(500).json({
      success: false,
      error: "Failed to create table",
      message: error instanceof Error ? error.message : String(error)
    });
  }
}

export { adminUsers as a, backups as b, devices as c, db as d, communicationLogs as e, backupSchedules as f, servers as g, closeConnection as h, handler as i, remoteCommands as r, storageConfig as s, uploadProgress as u };
