import Database from 'better-sqlite3'
import path from 'path'
import { Employee, User, SkillDefinition } from '@skillmate/shared'
import bcrypt from 'bcryptjs'
import { v4 as uuidv4 } from 'uuid'
import { db as secureDb, encryptedDb, initializeSecureDatabase } from './secureDatabase'
export { initializeSecureDatabase } from './secureDatabase'

// Export the secure database instance
export const db = secureDb

export function initializeDatabase() {
  // Users table
  db.exec(`
    CREATE TABLE IF NOT EXISTS users (
      id TEXT PRIMARY KEY,
      username TEXT UNIQUE NOT NULL,
      email TEXT UNIQUE NOT NULL,
      password TEXT NOT NULL,
      role TEXT NOT NULL CHECK(role IN ('admin', 'superuser', 'user')),
      employee_id TEXT,
      last_login TEXT,
      is_active INTEGER DEFAULT 1,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL
    )
  `)

  // Profiles table (erweitert für Yellow Pages)
  db.exec(`
    CREATE TABLE IF NOT EXISTS profiles (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      department TEXT,
      location TEXT,
      role TEXT,
      email TEXT,
      phone TEXT,
      teams_link TEXT,
      job_category TEXT CHECK(job_category IN ('Technik', 'IT & Digitalisierung', 'Verwaltung', 'F&E', 'Kommunikation & HR', 'Produktion', 'Sonstiges')),
      job_title TEXT,
      job_desc TEXT,
      consent_public_profile INTEGER DEFAULT 0,
      consent_searchable INTEGER DEFAULT 0,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL,
      updated_by TEXT NOT NULL,
      review_due_at TEXT,
      search_vector TEXT
    )
  `)
  
  // Volltext-Index für Suche
  db.exec(`
    CREATE INDEX IF NOT EXISTS idx_profiles_search 
    ON profiles(search_vector);
    
    CREATE INDEX IF NOT EXISTS idx_profiles_department 
    ON profiles(department);
    
    CREATE INDEX IF NOT EXISTS idx_profiles_location 
    ON profiles(location);
    
    CREATE INDEX IF NOT EXISTS idx_profiles_job_category 
    ON profiles(job_category);
    
    CREATE INDEX IF NOT EXISTS idx_profiles_review_due 
    ON profiles(review_due_at);
  `)

  // Employees table (für Kompatibilität beibehalten)
  db.exec(`
    CREATE TABLE IF NOT EXISTS employees (
      id TEXT PRIMARY KEY,
      first_name TEXT NOT NULL,
      last_name TEXT NOT NULL,
      employee_number TEXT UNIQUE NOT NULL,
      photo TEXT,
      position TEXT NOT NULL,
      department TEXT NOT NULL,
      email TEXT NOT NULL,
      phone TEXT NOT NULL,
      mobile TEXT,
      office TEXT,
      availability TEXT NOT NULL,
      clearance_level TEXT,
      clearance_valid_until TEXT,
      clearance_issued_date TEXT,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL,
      created_by TEXT NOT NULL,
      updated_by TEXT
    )
  `)

  // Skills table
  db.exec(`
    CREATE TABLE IF NOT EXISTS skills (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      category TEXT NOT NULL,
      description TEXT,
      requires_certification INTEGER DEFAULT 0,
      expires_after INTEGER
    )
  `)

  // Employee skills junction table
  db.exec(`
    CREATE TABLE IF NOT EXISTS employee_skills (
      employee_id TEXT NOT NULL,
      skill_id TEXT NOT NULL,
      level TEXT,
      verified INTEGER DEFAULT 0,
      verified_by TEXT,
      verified_date TEXT,
      PRIMARY KEY (employee_id, skill_id),
      FOREIGN KEY (employee_id) REFERENCES employees(id) ON DELETE CASCADE,
      FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE
    )
  `)

  // Profile Kompetenzen (Arrays als separate Tabellen)
  db.exec(`
    CREATE TABLE IF NOT EXISTS profile_domains (
      profile_id TEXT NOT NULL,
      domain TEXT NOT NULL,
      PRIMARY KEY (profile_id, domain),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_tools (
      profile_id TEXT NOT NULL,
      tool TEXT NOT NULL,
      PRIMARY KEY (profile_id, tool),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_methods (
      profile_id TEXT NOT NULL,
      method TEXT NOT NULL,
      PRIMARY KEY (profile_id, method),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_industry_knowledge (
      profile_id TEXT NOT NULL,
      knowledge TEXT NOT NULL,
      PRIMARY KEY (profile_id, knowledge),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_regulatory (
      profile_id TEXT NOT NULL,
      regulation TEXT NOT NULL,
      PRIMARY KEY (profile_id, regulation),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_networks (
      profile_id TEXT NOT NULL,
      network TEXT NOT NULL,
      PRIMARY KEY (profile_id, network),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_digital_skills (
      profile_id TEXT NOT NULL,
      skill TEXT NOT NULL,
      PRIMARY KEY (profile_id, skill),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS profile_social_skills (
      profile_id TEXT NOT NULL,
      skill TEXT NOT NULL,
      PRIMARY KEY (profile_id, skill),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
  `)
  
  // Profile Sprachen
  db.exec(`
    CREATE TABLE IF NOT EXISTS profile_languages (
      profile_id TEXT NOT NULL,
      code TEXT NOT NULL,
      level TEXT NOT NULL CHECK(level IN ('basic', 'fluent', 'native', 'business')),
      PRIMARY KEY (profile_id, code),
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
  `)
  
  // Profile Projekte
  db.exec(`
    CREATE TABLE IF NOT EXISTS profile_projects (
      id TEXT PRIMARY KEY,
      profile_id TEXT NOT NULL,
      title TEXT NOT NULL,
      role TEXT,
      summary TEXT,
      created_at TEXT NOT NULL,
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE TABLE IF NOT EXISTS project_links (
      project_id TEXT NOT NULL,
      link TEXT NOT NULL,
      PRIMARY KEY (project_id, link),
      FOREIGN KEY (project_id) REFERENCES profile_projects(id) ON DELETE CASCADE
    );
  `)
  
  // Language skills table (für Kompatibilität)
  db.exec(`
    CREATE TABLE IF NOT EXISTS language_skills (
      id TEXT PRIMARY KEY,
      employee_id TEXT NOT NULL,
      language TEXT NOT NULL,
      proficiency TEXT NOT NULL,
      certified INTEGER DEFAULT 0,
      certificate_type TEXT,
      is_native INTEGER DEFAULT 0,
      can_interpret INTEGER DEFAULT 0,
      FOREIGN KEY (employee_id) REFERENCES employees(id) ON DELETE CASCADE
    )
  `)

  // Specializations table
  db.exec(`
    CREATE TABLE IF NOT EXISTS specializations (
      id TEXT PRIMARY KEY,
      employee_id TEXT NOT NULL,
      name TEXT NOT NULL,
      FOREIGN KEY (employee_id) REFERENCES employees(id) ON DELETE CASCADE
    )
  `)

  // Sync log table
  db.exec(`
    CREATE TABLE IF NOT EXISTS sync_log (
      id TEXT PRIMARY KEY,
      sync_time TEXT NOT NULL,
      success INTEGER NOT NULL,
      items_synced INTEGER,
      error_message TEXT,
      duration INTEGER
    )
  `)

  // Create default admin user if not exists
  const adminExists = db.prepare('SELECT id FROM users WHERE username = ?').get('admin')
  if (!adminExists) {
    const hashedPassword = bcrypt.hashSync('admin123', 10)
    const now = new Date().toISOString()
    db.prepare(`
      INSERT INTO users (id, username, email, password, role, is_active, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `).run(
      uuidv4(),
      'admin',
      'admin@skillmate.local',
      hashedPassword,
      'admin',
      1,
      now,
      now
    )
  }

  // Workspace Management Tables
  
  // Workspaces (Desks, Meeting Rooms, etc.)
  db.exec(`
    CREATE TABLE IF NOT EXISTS workspaces (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      type TEXT NOT NULL CHECK(type IN ('desk', 'meeting_room', 'phone_booth', 'parking', 'locker')),
      floor TEXT NOT NULL,
      building TEXT,
      capacity INTEGER DEFAULT 1,
      equipment TEXT, -- JSON array of equipment
      position_x INTEGER, -- For floor plan visualization
      position_y INTEGER,
      is_active INTEGER DEFAULT 1,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL
    )
  `)

  // Bookings table
  db.exec(`
    CREATE TABLE IF NOT EXISTS bookings (
      id TEXT PRIMARY KEY,
      workspace_id TEXT NOT NULL,
      user_id TEXT NOT NULL,
      employee_id TEXT NOT NULL,
      start_time TEXT NOT NULL,
      end_time TEXT NOT NULL,
      status TEXT NOT NULL CHECK(status IN ('confirmed', 'cancelled', 'completed', 'no_show')),
      check_in_time TEXT,
      check_out_time TEXT,
      notes TEXT,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL,
      FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
      FOREIGN KEY (user_id) REFERENCES users(id),
      FOREIGN KEY (employee_id) REFERENCES employees(id)
    )
  `)

  // Recurring bookings
  db.exec(`
    CREATE TABLE IF NOT EXISTS recurring_bookings (
      id TEXT PRIMARY KEY,
      workspace_id TEXT NOT NULL,
      user_id TEXT NOT NULL,
      employee_id TEXT NOT NULL,
      start_date TEXT NOT NULL,
      end_date TEXT NOT NULL,
      time_start TEXT NOT NULL,
      time_end TEXT NOT NULL,
      days_of_week TEXT NOT NULL, -- JSON array of days [1,2,3,4,5] for Mon-Fri
      created_at TEXT NOT NULL,
      FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
      FOREIGN KEY (user_id) REFERENCES users(id),
      FOREIGN KEY (employee_id) REFERENCES employees(id)
    )
  `)

  // Booking rules and restrictions
  db.exec(`
    CREATE TABLE IF NOT EXISTS booking_rules (
      id TEXT PRIMARY KEY,
      workspace_type TEXT,
      max_duration_hours INTEGER,
      max_advance_days INTEGER,
      min_advance_hours INTEGER,
      max_bookings_per_user_per_day INTEGER,
      max_bookings_per_user_per_week INTEGER,
      auto_release_minutes INTEGER, -- Auto-release if not checked in
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL
    )
  `)

  // Analytics data
  db.exec(`
    CREATE TABLE IF NOT EXISTS workspace_analytics (
      id TEXT PRIMARY KEY,
      workspace_id TEXT NOT NULL,
      date TEXT NOT NULL,
      total_bookings INTEGER DEFAULT 0,
      total_hours_booked REAL DEFAULT 0,
      utilization_rate REAL DEFAULT 0,
      no_show_count INTEGER DEFAULT 0,
      unique_users INTEGER DEFAULT 0,
      peak_hour INTEGER,
      FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
      UNIQUE(workspace_id, date)
    )
  `)

  // Floor plans
  db.exec(`
    CREATE TABLE IF NOT EXISTS floor_plans (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      floor TEXT NOT NULL,
      building TEXT,
      image_url TEXT,
      svg_data TEXT, -- SVG data for interactive floor plan
      width INTEGER,
      height INTEGER,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL
    )
  `)

  // Audit Log für Änderungsverfolgung
  db.exec(`
    CREATE TABLE IF NOT EXISTS audit_log (
      id TEXT PRIMARY KEY,
      entity_type TEXT NOT NULL,
      entity_id TEXT NOT NULL,
      action TEXT NOT NULL CHECK(action IN ('create', 'update', 'delete')),
      user_id TEXT NOT NULL,
      changes TEXT, -- JSON mit Änderungen
      timestamp TEXT NOT NULL,
      ip_address TEXT,
      user_agent TEXT
    );
    
    CREATE INDEX IF NOT EXISTS idx_audit_entity ON audit_log(entity_type, entity_id);
    CREATE INDEX IF NOT EXISTS idx_audit_user ON audit_log(user_id);
    CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON audit_log(timestamp);
  `)
  
  // Reminder-System
  db.exec(`
    CREATE TABLE IF NOT EXISTS reminders (
      id TEXT PRIMARY KEY,
      profile_id TEXT NOT NULL,
      type TEXT NOT NULL CHECK(type IN ('annual_update', 'overdue', 'custom')),
      message TEXT,
      sent_at TEXT,
      acknowledged_at TEXT,
      created_at TEXT NOT NULL,
      FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
    );
    
    CREATE INDEX IF NOT EXISTS idx_reminders_profile ON reminders(profile_id);
    CREATE INDEX IF NOT EXISTS idx_reminders_sent ON reminders(sent_at);
  `)
  
  // Kontrollierte Vokabulare/Tags
  db.exec(`
    CREATE TABLE IF NOT EXISTS controlled_vocabulary (
      id TEXT PRIMARY KEY,
      category TEXT NOT NULL,
      value TEXT NOT NULL,
      description TEXT,
      is_active INTEGER DEFAULT 1,
      created_at TEXT NOT NULL,
      UNIQUE(category, value)
    );
    
    CREATE INDEX IF NOT EXISTS idx_vocab_category ON controlled_vocabulary(category);
  `)
  
  // Create indexes for better performance
  db.exec(`
    CREATE INDEX IF NOT EXISTS idx_employees_availability ON employees(availability);
    CREATE INDEX IF NOT EXISTS idx_employees_department ON employees(department);
    CREATE INDEX IF NOT EXISTS idx_employee_skills_employee ON employee_skills(employee_id);
    CREATE INDEX IF NOT EXISTS idx_employee_skills_skill ON employee_skills(skill_id);
    CREATE INDEX IF NOT EXISTS idx_language_skills_employee ON language_skills(employee_id);
    CREATE INDEX IF NOT EXISTS idx_specializations_employee ON specializations(employee_id);
    CREATE INDEX IF NOT EXISTS idx_bookings_workspace ON bookings(workspace_id);
    CREATE INDEX IF NOT EXISTS idx_bookings_user ON bookings(user_id);
    CREATE INDEX IF NOT EXISTS idx_bookings_start_time ON bookings(start_time);
    CREATE INDEX IF NOT EXISTS idx_bookings_status ON bookings(status);
    CREATE INDEX IF NOT EXISTS idx_workspace_analytics_date ON workspace_analytics(date);
  `)
}