// src/app/(frontend)/api/workflows/route.ts
// Dedizierte Workflows-API für Frontend-Anwendungen

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import type { Where } from 'payload'
import config from '@payload-config'
import type { Media } from '@/payload-types'

type Locale = 'de' | 'en' | 'all'
import {
  searchLimiter,
  rateLimitHeaders,
  getClientIpFromRequest,
  isIpBlocked,
} from '@/lib/security'

// Validation constants
const WORKFLOW_RATE_LIMIT = 30

// Valid workflow types
const WORKFLOW_TYPES = [
  'project',
  'business',
  'approval',
  'onboarding',
  'support',
  'development',
  'marketing',
  'other',
] as const
type WorkflowType = (typeof WORKFLOW_TYPES)[number]

// Valid complexity values (must match Workflows.ts select options)
const COMPLEXITY_VALUES = ['simple', 'medium', 'complex', 'very_complex'] as const
type ComplexityValue = (typeof COMPLEXITY_VALUES)[number]

interface WorkflowStep {
  name: string
  description?: unknown
  shortDescription?: string
  stepType?: string
  priority?: string
  estimatedDuration?: string
  responsible?: string
  icon?: string
  dependencies?: {
    dependsOnSteps?: string
    canRunParallel?: boolean
    isBlocking?: boolean
  }
  conditions?: Array<{
    condition: string
    nextStep?: string
    color?: string
  }>
  checklist?: Array<{
    item: string
    isRequired?: boolean
  }>
  resources?: Array<{
    name: string
    type?: string
    file?: Media | number
    url?: string
    description?: string
  }>
  outputs?: Array<{
    name: string
    description?: string
  }>
  metadata?: unknown
}

interface WorkflowPhase {
  name: string
  description?: string
  icon?: string
  color?: string
  estimatedDuration?: string
  responsible?: string
  steps: WorkflowStep[]
  deliverables?: Array<{
    name: string
    description?: string
  }>
}

export async function GET(request: NextRequest) {
  try {
    // IP-Blocklist prüfen
    const ip = getClientIpFromRequest(request)
    if (isIpBlocked(ip)) {
      return NextResponse.json({ error: 'Access denied' }, { status: 403 })
    }

    // Rate limiting
    const rateLimit = await searchLimiter.check(ip)
    if (!rateLimit.allowed) {
      return NextResponse.json(
        { error: 'Too many requests. Please try again later.' },
        { status: 429, headers: rateLimitHeaders(rateLimit, WORKFLOW_RATE_LIMIT) }
      )
    }

    // Parse query parameters
    const { searchParams } = new URL(request.url)

    const tenantParam = searchParams.get('tenant')
    const slugParam = searchParams.get('slug')?.trim()
    const typeParam = searchParams.get('type')?.trim()
    const localeParam = searchParams.get('locale')?.trim()
    const complexityParam = searchParams.get('complexity')?.trim()

    // Validate tenant - REQUIRED for tenant isolation
    if (!tenantParam) {
      return NextResponse.json(
        { error: 'Tenant ID is required. Use ?tenant=<id> to specify the tenant.' },
        { status: 400 }
      )
    }
    const tenantId = parseInt(tenantParam, 10)
    if (isNaN(tenantId) || tenantId < 1) {
      return NextResponse.json({ error: 'Invalid tenant ID' }, { status: 400 })
    }

    // Validate locale
    const validLocales: Locale[] = ['de', 'en']
    const locale: Locale = localeParam && validLocales.includes(localeParam as Locale) ? (localeParam as Locale) : 'de'

    // Validate type if provided
    if (typeParam && !WORKFLOW_TYPES.includes(typeParam as WorkflowType)) {
      return NextResponse.json(
        { error: `Invalid type. Must be one of: ${WORKFLOW_TYPES.join(', ')}` },
        { status: 400 }
      )
    }

    // Validate complexity if provided
    if (complexityParam && !COMPLEXITY_VALUES.includes(complexityParam as ComplexityValue)) {
      return NextResponse.json(
        { error: `Invalid complexity. Must be one of: ${COMPLEXITY_VALUES.join(', ')}` },
        { status: 400 }
      )
    }

    // Build where clause
    const where: Where = {
      status: { equals: 'published' },
      tenant: { equals: tenantId },
    }

    // Filter by slug (single workflow)
    if (slugParam) {
      where.slug = { equals: slugParam }
    }

    // Filter by type
    if (typeParam) {
      where.type = { equals: typeParam }
    }

    // Get payload instance
    const payload = await getPayload({ config })

    // Execute query
    const result = await payload.find({
      collection: 'workflows',
      where: where as Where,
      sort: '-updatedAt',
      limit: slugParam ? 1 : 100, // Single or list
      locale,
      depth: 2, // Load media relations
    })

    if (slugParam && result.docs.length === 0) {
      return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
    }

    // Transform workflows
    const transformedDocs = result.docs.map((workflow) => {
      const phases = (workflow.phases || []) as WorkflowPhase[]

      // Filter by complexity if specified
      if (
        complexityParam &&
        (workflow.properties as { complexity?: string })?.complexity !== complexityParam
      ) {
        return null
      }

      // Calculate statistics
      let totalSteps = 0
      let totalChecklists = 0
      const stepTypes: Record<string, number> = {}

      // Transform phases
      const transformedPhases = phases.map((phase, phaseIndex) => {
        const steps = (phase.steps || []) as WorkflowStep[]

        const transformedSteps = steps.map((step, stepIndex) => {
          totalSteps++

          // Count step types
          const stepType = step.stepType || 'task'
          stepTypes[stepType] = (stepTypes[stepType] || 0) + 1

          // Count checklists
          totalChecklists += (step.checklist || []).length

          // Transform resources
          const resources = (step.resources || []).map((resource) => {
            const file = resource.file as Media | null
            return {
              name: resource.name,
              type: resource.type || 'document',
              fileUrl: file?.url || null,
              url: resource.url || null,
              description: resource.description || null,
            }
          })

          return {
            index: stepIndex + 1,
            globalIndex: totalSteps,
            name: step.name,
            description: step.description || null,
            shortDescription: step.shortDescription || null,
            stepType: step.stepType || 'task',
            priority: step.priority || 'normal',
            estimatedDuration: step.estimatedDuration || null,
            responsible: step.responsible || null,
            icon: step.icon || null,
            dependencies: step.dependencies
              ? {
                  dependsOnSteps: step.dependencies.dependsOnSteps || null,
                  canRunParallel: step.dependencies.canRunParallel || false,
                  isBlocking: step.dependencies.isBlocking !== false,
                }
              : null,
            conditions:
              step.stepType === 'decision'
                ? (step.conditions || []).map((c) => ({
                    condition: c.condition,
                    nextStep: c.nextStep || null,
                    color: c.color || null,
                  }))
                : null,
            checklist: (step.checklist || []).map((item) => ({
              item: item.item,
              isRequired: item.isRequired !== false,
            })),
            resources: resources.length > 0 ? resources : null,
            outputs: (step.outputs || []).map((o) => ({
              name: o.name,
              description: o.description || null,
            })),
            metadata: step.metadata || null,
          }
        })

        return {
          index: phaseIndex + 1,
          name: phase.name,
          description: phase.description || null,
          icon: phase.icon || null,
          color: phase.color || null,
          estimatedDuration: phase.estimatedDuration || null,
          responsible: phase.responsible || null,
          stepCount: transformedSteps.length,
          steps: transformedSteps,
          deliverables: (phase.deliverables || []).map((d) => ({
            name: d.name,
            description: d.description || null,
          })),
        }
      })

      // Transform global resources
      const globalResources = (
        workflow.globalResources as Array<{
          name: string
          type?: string
          file?: Media | number
          url?: string
          description?: string
        }>
      )?.map((resource) => {
        const file = resource.file as Media | null
        return {
          name: resource.name,
          type: resource.type || 'document',
          fileUrl: file?.url || null,
          url: resource.url || null,
          description: resource.description || null,
        }
      })

      const image = workflow.image as Media | null

      return {
        id: workflow.id,
        name: workflow.name,
        slug: workflow.slug,
        description: workflow.description || null,
        shortDescription: workflow.shortDescription || null,
        type: workflow.type,
        image: image
          ? {
              url: image.url,
              alt: image.alt || workflow.name,
              width: image.width,
              height: image.height,
            }
          : null,
        properties: workflow.properties || null,
        displayOptions: workflow.displayOptions || null,
        phases: transformedPhases,
        globalResources: globalResources?.length ? globalResources : null,
        statistics: {
          phaseCount: transformedPhases.length,
          totalSteps,
          totalChecklists,
          stepTypes,
        },
        seo: workflow.seo || null,
      }
    })

    // Filter out null entries (from complexity filter)
    const filteredDocs = transformedDocs.filter(Boolean)

    // Single workflow response
    if (slugParam) {
      if (filteredDocs.length === 0) {
        return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
      }

      return NextResponse.json(
        {
          workflow: filteredDocs[0],
          locale,
        },
        {
          headers: {
            ...rateLimitHeaders(rateLimit, WORKFLOW_RATE_LIMIT),
            'Cache-Control': 'public, max-age=60, s-maxage=300',
          },
        }
      )
    }

    // List response
    return NextResponse.json(
      {
        docs: filteredDocs,
        total: filteredDocs.length,
        filters: {
          tenant: tenantId,
          type: typeParam || null,
          complexity: complexityParam || null,
          locale,
        },
      },
      {
        headers: {
          ...rateLimitHeaders(rateLimit, WORKFLOW_RATE_LIMIT),
          'Cache-Control': 'public, max-age=60, s-maxage=120',
        },
      }
    )
  } catch (error) {
    console.error('[Workflow API] Error:', error)
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
  }
}
