import { Router, Response, NextFunction } from 'express'
import { v4 as uuidv4 } from 'uuid'
import { body, validationResult, query } from 'express-validator'
import { db } from '../config/database'
import { authenticate, authorize, AuthRequest } from '../middleware/auth'
// Profile Interface direkt definiert, da shared module noch nicht aktualisiert
interface Profile {
  id: string
  name: string
  department?: string
  location?: string
  role?: string
  contacts?: {
    email?: string
    phone?: string
    teams?: string
  }
  domains?: string[]
  tools?: string[]
  methods?: string[]
  industryKnowledge?: string[]
  regulatory?: string[]
  languages?: { code: string; level: string }[]
  projects?: { title: string; role?: string; summary?: string; links?: string[] }[]
  networks?: string[]
  digitalSkills?: string[]
  socialSkills?: string[]
  jobCategory?: string
  jobTitle?: string
  jobDesc?: string
  consentPublicProfile: boolean
  consentSearchable: boolean
  updatedAt: string
  updatedBy: string
  reviewDueAt?: string
}

const router = Router()

// Hilfsfunktion f\u00fcr Volltextsuche
function buildSearchVector(profile: any): string {
  const parts = [
    profile.name,
    profile.role,
    profile.jobTitle,
    profile.jobDesc,
    ...(profile.domains || []),
    ...(profile.tools || []),
    ...(profile.methods || []),
    ...(profile.industryKnowledge || []),
    ...(profile.digitalSkills || [])
  ].filter(Boolean)
  
  return parts.join(' ').toLowerCase()
}

// GET /api/profiles - Suche mit Facetten
router.get('/', 
  authenticate,
  [
    query('query').optional().trim(),
    query('dept').optional(),
    query('loc').optional(),
    query('jobCat').optional(),
    query('tools').optional(),
    query('methods').optional(),
    query('lang').optional(),
    query('page').optional().isInt({ min: 1 }).toInt(),
    query('pageSize').optional().isInt({ min: 1, max: 100 }).toInt(),
    query('sort').optional().isIn(['recency', 'relevance'])
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) {
        return res.status(400).json({ 
          success: false, 
          error: { message: 'Invalid query parameters', details: errors.array() } 
        })
      }

      const {
        query: searchQuery,
        dept,
        loc,
        jobCat,
        tools,
        methods,
        lang,
        page = 1,
        pageSize = 20,
        sort = 'relevance'
      } = req.query

      // Basis-Query mit Consent-Pr\u00fcfung
      let sql = `
        SELECT DISTINCT p.*
        FROM profiles p
        WHERE (p.consent_searchable = 1 OR p.updated_by = ?)
      `
      const params: any[] = [req.user!.id]

      // Volltextsuche
      if (searchQuery) {
        sql += ` AND p.search_vector LIKE ?`
        params.push(`%${searchQuery}%`)
      }

      // Facettenfilter
      if (dept) {
        sql += ` AND p.department = ?`
        params.push(dept)
      }

      if (loc) {
        sql += ` AND p.location = ?`
        params.push(loc)
      }

      if (jobCat) {
        sql += ` AND p.job_category = ?`
        params.push(jobCat)
      }

      // Tool-Filter
      if (tools) {
        const toolList = tools.toString().split(',')
        sql += ` AND EXISTS (
          SELECT 1 FROM profile_tools pt 
          WHERE pt.profile_id = p.id 
          AND pt.tool IN (${toolList.map(() => '?').join(',')})
        )`
        params.push(...toolList)
      }

      // Methoden-Filter
      if (methods) {
        const methodList = methods.toString().split(',')
        sql += ` AND EXISTS (
          SELECT 1 FROM profile_methods pm 
          WHERE pm.profile_id = p.id 
          AND pm.method IN (${methodList.map(() => '?').join(',')})
        )`
        params.push(...methodList)
      }

      // Sprachen-Filter
      if (lang) {
        const [langCode, level] = lang.toString().split(':')
        sql += ` AND EXISTS (
          SELECT 1 FROM profile_languages pl 
          WHERE pl.profile_id = p.id 
          AND pl.code = ?
          ${level ? 'AND pl.level = ?' : ''}
        )`
        params.push(langCode)
        if (level) params.push(level)
      }

      // Sortierung
      if (sort === 'recency') {
        sql += ` ORDER BY p.updated_at DESC`
      } else {
        sql += ` ORDER BY p.updated_at DESC` // TODO: Ranking nach Relevanz
      }

      // Pagination
      const offset = ((page as number) - 1) * (pageSize as number)
      sql += ` LIMIT ? OFFSET ?`
      params.push(pageSize, offset)

      const profiles = db.prepare(sql).all(...params)

      // Lade zus\u00e4tzliche Daten f\u00fcr jedes Profil
      const enrichedProfiles = profiles.map((profile: any) => {
        // Lade Arrays
        const domains = db.prepare('SELECT domain FROM profile_domains WHERE profile_id = ?').all(profile.id).map((r: any) => r.domain)
        const tools = db.prepare('SELECT tool FROM profile_tools WHERE profile_id = ?').all(profile.id).map((r: any) => r.tool)
        const methods = db.prepare('SELECT method FROM profile_methods WHERE profile_id = ?').all(profile.id).map((r: any) => r.method)
        const industryKnowledge = db.prepare('SELECT knowledge FROM profile_industry_knowledge WHERE profile_id = ?').all(profile.id).map((r: any) => r.knowledge)
        const regulatory = db.prepare('SELECT regulation FROM profile_regulatory WHERE profile_id = ?').all(profile.id).map((r: any) => r.regulation)
        const networks = db.prepare('SELECT network FROM profile_networks WHERE profile_id = ?').all(profile.id).map((r: any) => r.network)
        const digitalSkills = db.prepare('SELECT skill FROM profile_digital_skills WHERE profile_id = ?').all(profile.id).map((r: any) => r.skill)
        const socialSkills = db.prepare('SELECT skill FROM profile_social_skills WHERE profile_id = ?').all(profile.id).map((r: any) => r.skill)
        
        // Lade Sprachen
        const languages = db.prepare('SELECT code, level FROM profile_languages WHERE profile_id = ?').all(profile.id)
        
        // Lade Projekte
        const projects = db.prepare('SELECT id, title, role, summary FROM profile_projects WHERE profile_id = ?').all(profile.id)
        for (const project of projects as any[]) {
          project.links = db.prepare('SELECT link FROM project_links WHERE project_id = ?').all(project.id).map((r: any) => r.link)
          delete project.id
        }

        return {
          ...profile,
          contacts: {
            email: profile.email,
            phone: profile.phone,
            teams: profile.teams_link
          },
          domains,
          tools,
          methods,
          industryKnowledge,
          regulatory,
          networks,
          digitalSkills,
          socialSkills,
          languages,
          projects,
          consentPublicProfile: Boolean(profile.consent_public_profile),
          consentSearchable: Boolean(profile.consent_searchable)
        }
      })

      res.json({ 
        success: true, 
        data: enrichedProfiles,
        meta: {
          page,
          pageSize,
          total: (db.prepare('SELECT COUNT(DISTINCT id) as count FROM profiles WHERE consent_searchable = 1 OR updated_by = ?').get(req.user!.id) as any)?.count || 0
        }
      })
    } catch (error) {
      next(error)
    }
  }
)

// GET /api/profiles/:id - Einzelnes Profil
router.get('/:id',
  authenticate,
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { id } = req.params
      
      const profile = db.prepare(`
        SELECT * FROM profiles WHERE id = ?
      `).get(id) as any

      if (!profile) {
        return res.status(404).json({ 
          success: false, 
          error: { message: 'Profile not found' } 
        })
      }

      // Pr\u00fcfe Zugriffsrechte
      const isOwner = profile.updated_by === req.user!.id
      const isAdmin = req.user!.role === 'admin'
      
      if (!profile.consent_public_profile && !isOwner && !isAdmin) {
        return res.status(403).json({ 
          success: false, 
          error: { message: 'Access denied' } 
        })
      }

      // Lade zus\u00e4tzliche Daten
      const domains = db.prepare('SELECT domain FROM profile_domains WHERE profile_id = ?').all(id).map((r: any) => r.domain)
      const tools = db.prepare('SELECT tool FROM profile_tools WHERE profile_id = ?').all(id).map((r: any) => r.tool)
      const methods = db.prepare('SELECT method FROM profile_methods WHERE profile_id = ?').all(id).map((r: any) => r.method)
      const industryKnowledge = db.prepare('SELECT knowledge FROM profile_industry_knowledge WHERE profile_id = ?').all(id).map((r: any) => r.knowledge)
      const regulatory = db.prepare('SELECT regulation FROM profile_regulatory WHERE profile_id = ?').all(id).map((r: any) => r.regulation)
      const networks = db.prepare('SELECT network FROM profile_networks WHERE profile_id = ?').all(id).map((r: any) => r.network)
      const digitalSkills = db.prepare('SELECT skill FROM profile_digital_skills WHERE profile_id = ?').all(id).map((r: any) => r.skill)
      const socialSkills = db.prepare('SELECT skill FROM profile_social_skills WHERE profile_id = ?').all(id).map((r: any) => r.skill)
      const languages = db.prepare('SELECT code, level FROM profile_languages WHERE profile_id = ?').all(id)
      
      const projects = db.prepare('SELECT id, title, role, summary FROM profile_projects WHERE profile_id = ?').all(id)
      for (const project of projects as any[]) {
        project.links = db.prepare('SELECT link FROM project_links WHERE project_id = ?').all(project.id).map((r: any) => r.link)
        delete project.id
      }

      const enrichedProfile = {
        ...profile,
        contacts: {
          email: profile.email,
          phone: profile.phone,
          teams: profile.teams_link
        },
        domains,
        tools,
        methods,
        industryKnowledge,
        regulatory,
        networks,
        digitalSkills,
        socialSkills,
        languages,
        projects,
        consentPublicProfile: Boolean(profile.consent_public_profile),
        consentSearchable: Boolean(profile.consent_searchable)
      }

      res.json({ success: true, data: enrichedProfile })
    } catch (error) {
      next(error)
    }
  }
)

// POST /api/profiles - Neues Profil erstellen
router.post('/',
  authenticate,
  [
    body('name').notEmpty().trim(),
    body('consentPublicProfile').isBoolean(),
    body('consentSearchable').isBoolean()
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) {
        return res.status(400).json({ 
          success: false, 
          error: { message: 'Invalid input', details: errors.array() } 
        })
      }

      const profileId = uuidv4()
      const now = new Date().toISOString()
      const reviewDueAt = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString()

      const profileData = {
        ...req.body,
        id: profileId,
        created_at: now,
        updated_at: now,
        updated_by: req.user!.id,
        review_due_at: reviewDueAt,
        search_vector: buildSearchVector(req.body)
      }

      // Transaktion starten
      const transaction = db.transaction(() => {
        // Profil einf\u00fcgen
        db.prepare(`
          INSERT INTO profiles (
            id, name, department, location, role, email, phone, teams_link,
            job_category, job_title, job_desc,
            consent_public_profile, consent_searchable,
            created_at, updated_at, updated_by, review_due_at, search_vector
          ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `).run(
          profileId,
          profileData.name,
          profileData.department || null,
          profileData.location || null,
          profileData.role || null,
          profileData.contacts?.email || null,
          profileData.contacts?.phone || null,
          profileData.contacts?.teams || null,
          profileData.jobCategory || null,
          profileData.jobTitle || null,
          profileData.jobDesc || null,
          profileData.consentPublicProfile ? 1 : 0,
          profileData.consentSearchable ? 1 : 0,
          now,
          now,
          req.user!.id,
          reviewDueAt,
          profileData.search_vector
        )

        // Arrays einf\u00fcgen
        const insertArray = (table: string, field: string, values: string[]) => {
          if (values && values.length > 0) {
            const stmt = db.prepare(`INSERT INTO ${table} (profile_id, ${field}) VALUES (?, ?)`)
            for (const value of values) {
              stmt.run(profileId, value)
            }
          }
        }

        insertArray('profile_domains', 'domain', profileData.domains)
        insertArray('profile_tools', 'tool', profileData.tools)
        insertArray('profile_methods', 'method', profileData.methods)
        insertArray('profile_industry_knowledge', 'knowledge', profileData.industryKnowledge)
        insertArray('profile_regulatory', 'regulation', profileData.regulatory)
        insertArray('profile_networks', 'network', profileData.networks)
        insertArray('profile_digital_skills', 'skill', profileData.digitalSkills)
        insertArray('profile_social_skills', 'skill', profileData.socialSkills)

        // Sprachen einf\u00fcgen
        if (profileData.languages && profileData.languages.length > 0) {
          const stmt = db.prepare(`INSERT INTO profile_languages (profile_id, code, level) VALUES (?, ?, ?)`)
          for (const lang of profileData.languages) {
            stmt.run(profileId, lang.code, lang.level)
          }
        }

        // Projekte einf\u00fcgen
        if (profileData.projects && profileData.projects.length > 0) {
          for (const project of profileData.projects) {
            const projectId = uuidv4()
            db.prepare(`
              INSERT INTO profile_projects (id, profile_id, title, role, summary, created_at)
              VALUES (?, ?, ?, ?, ?, ?)
            `).run(projectId, profileId, project.title, project.role || null, project.summary || null, now)
            
            if (project.links && project.links.length > 0) {
              const linkStmt = db.prepare(`INSERT INTO project_links (project_id, link) VALUES (?, ?)`)
              for (const link of project.links) {
                linkStmt.run(projectId, link)
              }
            }
          }
        }

        // Audit-Log
        db.prepare(`
          INSERT INTO audit_log (id, entity_type, entity_id, action, user_id, changes, timestamp)
          VALUES (?, ?, ?, ?, ?, ?, ?)
        `).run(
          uuidv4(),
          'profile',
          profileId,
          'create',
          req.user!.id,
          JSON.stringify(profileData),
          now
        )
      })

      transaction()

      res.status(201).json({ 
        success: true, 
        data: { id: profileId },
        message: 'Profile created successfully' 
      })
    } catch (error) {
      next(error)
    }
  }
)

// PUT /api/profiles/:id - Profil aktualisieren
router.put('/:id',
  authenticate,
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { id } = req.params
      const now = new Date().toISOString()
      const reviewDueAt = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString()

      // Pr\u00fcfe ob Profil existiert und Berechtigungen
      const existing = db.prepare('SELECT * FROM profiles WHERE id = ?').get(id) as any
      if (!existing) {
        return res.status(404).json({ 
          success: false, 
          error: { message: 'Profile not found' } 
        })
      }

      const isOwner = existing.updated_by === req.user!.id
      const isAdmin = req.user!.role === 'admin'
      
      if (!isOwner && !isAdmin) {
        return res.status(403).json({ 
          success: false, 
          error: { message: 'Access denied' } 
        })
      }

      const profileData = {
        ...req.body,
        updated_at: now,
        updated_by: req.user!.id,
        review_due_at: reviewDueAt,
        search_vector: buildSearchVector(req.body)
      }

      // Transaktion f\u00fcr Update
      const transaction = db.transaction(() => {
        // Profil aktualisieren
        db.prepare(`
          UPDATE profiles SET
            name = ?, department = ?, location = ?, role = ?,
            email = ?, phone = ?, teams_link = ?,
            job_category = ?, job_title = ?, job_desc = ?,
            consent_public_profile = ?, consent_searchable = ?,
            updated_at = ?, updated_by = ?, review_due_at = ?, search_vector = ?
          WHERE id = ?
        `).run(
          profileData.name,
          profileData.department || null,
          profileData.location || null,
          profileData.role || null,
          profileData.contacts?.email || null,
          profileData.contacts?.phone || null,
          profileData.contacts?.teams || null,
          profileData.jobCategory || null,
          profileData.jobTitle || null,
          profileData.jobDesc || null,
          profileData.consentPublicProfile ? 1 : 0,
          profileData.consentSearchable ? 1 : 0,
          now,
          req.user!.id,
          reviewDueAt,
          profileData.search_vector,
          id
        )

        // Arrays aktualisieren (l\u00f6schen und neu einf\u00fcgen)
        const updateArray = (table: string, field: string, values: string[]) => {
          db.prepare(`DELETE FROM ${table} WHERE profile_id = ?`).run(id)
          if (values && values.length > 0) {
            const stmt = db.prepare(`INSERT INTO ${table} (profile_id, ${field}) VALUES (?, ?)`)
            for (const value of values) {
              stmt.run(id, value)
            }
          }
        }

        updateArray('profile_domains', 'domain', profileData.domains)
        updateArray('profile_tools', 'tool', profileData.tools)
        updateArray('profile_methods', 'method', profileData.methods)
        updateArray('profile_industry_knowledge', 'knowledge', profileData.industryKnowledge)
        updateArray('profile_regulatory', 'regulation', profileData.regulatory)
        updateArray('profile_networks', 'network', profileData.networks)
        updateArray('profile_digital_skills', 'skill', profileData.digitalSkills)
        updateArray('profile_social_skills', 'skill', profileData.socialSkills)

        // Sprachen aktualisieren
        db.prepare('DELETE FROM profile_languages WHERE profile_id = ?').run(id)
        if (profileData.languages && profileData.languages.length > 0) {
          const stmt = db.prepare(`INSERT INTO profile_languages (profile_id, code, level) VALUES (?, ?, ?)`)
          for (const lang of profileData.languages) {
            stmt.run(id, lang.code, lang.level)
          }
        }

        // Projekte aktualisieren
        db.prepare('DELETE FROM profile_projects WHERE profile_id = ?').run(id)
        if (profileData.projects && profileData.projects.length > 0) {
          for (const project of profileData.projects) {
            const projectId = uuidv4()
            db.prepare(`
              INSERT INTO profile_projects (id, profile_id, title, role, summary, created_at)
              VALUES (?, ?, ?, ?, ?, ?)
            `).run(projectId, id, project.title, project.role || null, project.summary || null, now)
            
            if (project.links && project.links.length > 0) {
              const linkStmt = db.prepare(`INSERT INTO project_links (project_id, link) VALUES (?, ?)`)
              for (const link of project.links) {
                linkStmt.run(projectId, link)
              }
            }
          }
        }

        // Audit-Log
        db.prepare(`
          INSERT INTO audit_log (id, entity_type, entity_id, action, user_id, changes, timestamp)
          VALUES (?, ?, ?, ?, ?, ?, ?)
        `).run(
          uuidv4(),
          'profile',
          id,
          'update',
          req.user!.id,
          JSON.stringify({ before: existing, after: profileData }),
          now
        )
      })

      transaction()

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

// GET /api/profiles/facets - Facettenwerte f\u00fcr Filter
router.get('/facets',
  authenticate,
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const facets = {
        departments: db.prepare('SELECT DISTINCT department FROM profiles WHERE department IS NOT NULL AND consent_searchable = 1 ORDER BY department').all().map((r: any) => r.department),
        locations: db.prepare('SELECT DISTINCT location FROM profiles WHERE location IS NOT NULL AND consent_searchable = 1 ORDER BY location').all().map((r: any) => r.location),
        jobCategories: db.prepare('SELECT DISTINCT job_category FROM profiles WHERE job_category IS NOT NULL AND consent_searchable = 1 ORDER BY job_category').all().map((r: any) => r.job_category),
        tools: db.prepare('SELECT DISTINCT tool FROM profile_tools pt JOIN profiles p ON pt.profile_id = p.id WHERE p.consent_searchable = 1 ORDER BY tool').all().map((r: any) => r.tool),
        methods: db.prepare('SELECT DISTINCT method FROM profile_methods pm JOIN profiles p ON pm.profile_id = p.id WHERE p.consent_searchable = 1 ORDER BY method').all().map((r: any) => r.method),
        languages: db.prepare('SELECT DISTINCT code, level FROM profile_languages pl JOIN profiles p ON pl.profile_id = p.id WHERE p.consent_searchable = 1 ORDER BY code, level').all()
      }

      res.json({ success: true, data: facets })
    } catch (error) {
      next(error)
    }
  }
)

// GET /api/profiles/reminders/overdue - Veraltete Profile (Admin)
router.get('/reminders/overdue',
  authenticate,
  authorize('admin'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const now = new Date().toISOString()
      
      const overdueProfiles = db.prepare(`
        SELECT id, name, department, updated_at, review_due_at
        FROM profiles
        WHERE review_due_at < ?
        ORDER BY review_due_at ASC
      `).all(now)

      res.json({ success: true, data: overdueProfiles })
    } catch (error) {
      next(error)
    }
  }
)

// POST /api/profiles/export - Export-Funktionalit\u00e4t
router.post('/export',
  authenticate,
  authorize('admin', 'superuser'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { filter, format = 'json' } = req.body

      // Baue Query basierend auf Filter
      let sql = `SELECT * FROM profiles WHERE consent_searchable = 1`
      const params: any[] = []

      if (filter?.department) {
        sql += ` AND department = ?`
        params.push(filter.department)
      }

      if (filter?.location) {
        sql += ` AND location = ?`
        params.push(filter.location)
      }

      const profiles = db.prepare(sql).all(...params)

      if (format === 'csv') {
        // CSV-Export
        const csv = [
          'Name,Department,Location,Role,Email,Phone,Job Category,Job Title',
          ...profiles.map((p: any) => 
            `"${p.name}","${p.department || ''}","${p.location || ''}","${p.role || ''}","${p.email || ''}","${p.phone || ''}","${p.job_category || ''}","${p.job_title || ''}"`
          )
        ].join('\n')

        res.setHeader('Content-Type', 'text/csv')
        res.setHeader('Content-Disposition', 'attachment; filename=profiles.csv')
        res.send(csv)
      } else {
        // JSON-Export
        res.json({ success: true, data: profiles })
      }
    } catch (error) {
      next(error)
    }
  }
)

// POST /api/profiles/tags/suggest - Autocomplete f\u00fcr Tags
router.post('/tags/suggest',
  authenticate,
  [
    body('category').notEmpty(),
    body('query').notEmpty()
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { category, query } = req.body

      const suggestions = db.prepare(`
        SELECT value, description 
        FROM controlled_vocabulary 
        WHERE category = ? AND value LIKE ? AND is_active = 1
        ORDER BY value
        LIMIT 10
      `).all(category, `${query}%`)

      res.json({ success: true, data: suggestions })
    } catch (error) {
      next(error)
    }
  }
)

export default router