import { NextRequest, NextResponse } from 'next/server'
import {
  TOMGeneratorState,
  createEmptyTOMGeneratorState,
} from '@/lib/sdk/tom-generator/types'

/**
 * TOM Generator State API
 *
 * GET /api/sdk/v1/tom-generator/state?tenantId=xxx - Load TOM generator state
 * POST /api/sdk/v1/tom-generator/state - Save TOM generator state
 * DELETE /api/sdk/v1/tom-generator/state?tenantId=xxx - Clear state
 */

// =============================================================================
// STORAGE (In-Memory for development)
// =============================================================================

interface StoredTOMState {
  state: TOMGeneratorState
  version: number
  createdAt: string
  updatedAt: string
}

class InMemoryTOMStateStore {
  private store: Map<string, StoredTOMState> = new Map()

  async get(tenantId: string): Promise<StoredTOMState | null> {
    return this.store.get(tenantId) || null
  }

  async save(tenantId: string, state: TOMGeneratorState, expectedVersion?: number): Promise<StoredTOMState> {
    const existing = this.store.get(tenantId)

    if (expectedVersion !== undefined && existing && existing.version !== expectedVersion) {
      const error = new Error('Version conflict') as Error & { status: number }
      error.status = 409
      throw error
    }

    const now = new Date().toISOString()
    const newVersion = existing ? existing.version + 1 : 1

    const stored: StoredTOMState = {
      state: {
        ...state,
        updatedAt: new Date(now),
      },
      version: newVersion,
      createdAt: existing?.createdAt || now,
      updatedAt: now,
    }

    this.store.set(tenantId, stored)
    return stored
  }

  async delete(tenantId: string): Promise<boolean> {
    return this.store.delete(tenantId)
  }

  async list(): Promise<{ tenantId: string; updatedAt: string }[]> {
    const result: { tenantId: string; updatedAt: string }[] = []
    this.store.forEach((value, key) => {
      result.push({ tenantId: key, updatedAt: value.updatedAt })
    })
    return result
  }
}

const stateStore = new InMemoryTOMStateStore()

// =============================================================================
// HANDLERS
// =============================================================================

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const tenantId = searchParams.get('tenantId')

    // List all states if no tenantId provided
    if (!tenantId) {
      const states = await stateStore.list()
      return NextResponse.json({
        success: true,
        data: states,
      })
    }

    const stored = await stateStore.get(tenantId)

    if (!stored) {
      // Return empty state for new tenants
      const emptyState = createEmptyTOMGeneratorState(tenantId)
      return NextResponse.json({
        success: true,
        data: {
          tenantId,
          state: emptyState,
          version: 0,
          isNew: true,
        },
      })
    }

    return NextResponse.json({
      success: true,
      data: {
        tenantId,
        state: stored.state,
        version: stored.version,
        lastModified: stored.updatedAt,
      },
    })
  } catch (error) {
    console.error('Failed to load TOM generator state:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to load state' },
      { status: 500 }
    )
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { tenantId, state, version } = body

    if (!tenantId) {
      return NextResponse.json(
        { success: false, error: 'tenantId is required' },
        { status: 400 }
      )
    }

    if (!state) {
      return NextResponse.json(
        { success: false, error: 'state is required' },
        { status: 400 }
      )
    }

    // Deserialize dates
    const parsedState: TOMGeneratorState = {
      ...state,
      createdAt: new Date(state.createdAt),
      updatedAt: new Date(state.updatedAt),
      steps: state.steps.map((step: { id: string; completed: boolean; data: unknown; validatedAt: string | null }) => ({
        ...step,
        validatedAt: step.validatedAt ? new Date(step.validatedAt) : null,
      })),
      documents: state.documents?.map((doc: { uploadedAt: string; validFrom?: string; validUntil?: string; aiAnalysis?: { analyzedAt: string } }) => ({
        ...doc,
        uploadedAt: new Date(doc.uploadedAt),
        validFrom: doc.validFrom ? new Date(doc.validFrom) : null,
        validUntil: doc.validUntil ? new Date(doc.validUntil) : null,
        aiAnalysis: doc.aiAnalysis ? {
          ...doc.aiAnalysis,
          analyzedAt: new Date(doc.aiAnalysis.analyzedAt),
        } : null,
      })) || [],
      derivedTOMs: state.derivedTOMs?.map((tom: { implementationDate?: string; reviewDate?: string }) => ({
        ...tom,
        implementationDate: tom.implementationDate ? new Date(tom.implementationDate) : null,
        reviewDate: tom.reviewDate ? new Date(tom.reviewDate) : null,
      })) || [],
      gapAnalysis: state.gapAnalysis ? {
        ...state.gapAnalysis,
        generatedAt: new Date(state.gapAnalysis.generatedAt),
      } : null,
      exports: state.exports?.map((exp: { generatedAt: string }) => ({
        ...exp,
        generatedAt: new Date(exp.generatedAt),
      })) || [],
    }

    const stored = await stateStore.save(tenantId, parsedState, version)

    return NextResponse.json({
      success: true,
      data: {
        tenantId,
        state: stored.state,
        version: stored.version,
        lastModified: stored.updatedAt,
      },
    })
  } catch (error) {
    const err = error as Error & { status?: number }

    if (err.status === 409 || err.message === 'Version conflict') {
      return NextResponse.json(
        {
          success: false,
          error: 'Version conflict. State was modified by another request.',
          code: 'VERSION_CONFLICT',
        },
        { status: 409 }
      )
    }

    console.error('Failed to save TOM generator state:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to save state' },
      { status: 500 }
    )
  }
}

export async function DELETE(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const tenantId = searchParams.get('tenantId')

    if (!tenantId) {
      return NextResponse.json(
        { success: false, error: 'tenantId is required' },
        { status: 400 }
      )
    }

    const deleted = await stateStore.delete(tenantId)

    return NextResponse.json({
      success: true,
      tenantId,
      deleted,
      deletedAt: new Date().toISOString(),
    })
  } catch (error) {
    console.error('Failed to delete TOM generator state:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to delete state' },
      { status: 500 }
    )
  }
}

export async function OPTIONS() {
  return NextResponse.json(
    { status: 'ok' },
    {
      headers: {
        Allow: 'GET, POST, DELETE, OPTIONS',
      },
    }
  )
}
