import { getPayload } from 'payload'
import config from '@payload-config'
import { NextRequest, NextResponse } from 'next/server'
import { detectConflicts, type CalendarEvent } from '@/lib/youtube/ConflictDetectionService'

function resolveTitle(title: unknown): string {
  if (typeof title === 'string') return title
  if (title && typeof title === 'object') {
    const localized = title as Record<string, string>
    return localized.de || localized.en || 'Untitled'
  }
  return 'Untitled'
}

function resolveRelation(field: unknown): { id: number; name?: string } {
  if (field && typeof field === 'object' && 'id' in field) {
    const obj = field as { id: number; name?: string }
    return { id: obj.id, name: obj.name }
  }
  return { id: typeof field === 'number' ? field : 0 }
}

/**
 * GET /api/youtube/calendar
 *
 * Returns calendar events for FullCalendar with conflict detection.
 * Query params: channelId, start, end (ISO dates).
 */
export async function GET(req: NextRequest): Promise<NextResponse> {
  try {
    const payload = await getPayload({ config })
    const { user } = await payload.auth({ headers: req.headers })

    if (!user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { searchParams } = req.nextUrl
    const channelId = searchParams.get('channelId')
    const start = searchParams.get('start')
    const end = searchParams.get('end')

    if (!start || !end) {
      return NextResponse.json({ error: 'start and end required' }, { status: 400 })
    }

    const where: any = {
      scheduledPublishDate: {
        greater_than_equal: start,
        less_than_equal: end,
      },
      status: { not_equals: 'discarded' },
    }
    if (channelId && channelId !== 'all') {
      where.channel = { equals: parseInt(channelId) }
    }

    const [videos, channels] = await Promise.all([
      payload.find({
        collection: 'youtube-content',
        where,
        limit: 200,
        depth: 1,
        sort: 'scheduledPublishDate',
      }),
      payload.find({
        collection: 'youtube-channels',
        where: { status: { equals: 'active' } },
        limit: 50,
        depth: 0,
      }),
    ])

    // Build channel color lookup
    const channelColorMap = new Map<number, string>()
    for (const ch of channels.docs) {
      const branding = (ch as unknown as { branding?: { primaryColor?: string } }).branding
      channelColorMap.set(ch.id as number, branding?.primaryColor || '#3788d8')
    }

    // Build CalendarEvent array for conflict detection
    const calendarEvents: CalendarEvent[] = videos.docs.map((v) => {
      const doc = v as unknown as Record<string, unknown>
      const channel = resolveRelation(doc.channel)
      const series = resolveRelation(doc.series)

      return {
        id: doc.id as number,
        channelId: channel.id,
        scheduledDate: doc.scheduledPublishDate as string,
        contentType: (doc.format as CalendarEvent['contentType']) || 'longform',
        seriesId: series.id || undefined,
      }
    })

    // Get schedule config from first channel
    const defaultSchedule = { longformPerWeek: 1, shortsPerWeek: 4 }
    const firstChannel = channels.docs[0] as unknown as Record<string, unknown> | undefined
    const publishingSchedule = firstChannel?.publishingSchedule as
      | { longformPerWeek?: number; shortsPerWeek?: number }
      | undefined
    const scheduleConfig = {
      longformPerWeek: publishingSchedule?.longformPerWeek ?? defaultSchedule.longformPerWeek,
      shortsPerWeek: publishingSchedule?.shortsPerWeek ?? defaultSchedule.shortsPerWeek,
    }

    const conflicts = detectConflicts(calendarEvents, scheduleConfig)
    const conflictEventIds = new Set(conflicts.flatMap((c) => c.eventIds))

    // Format for FullCalendar
    const events = videos.docs.map((v) => {
      const doc = v as unknown as Record<string, unknown>
      const channel = resolveRelation(doc.channel)
      const series = resolveRelation(doc.series)

      return {
        id: String(doc.id),
        title: resolveTitle(doc.title),
        start: doc.scheduledPublishDate,
        color: channelColorMap.get(channel.id) || '#3788d8',
        extendedProps: {
          status: doc.status,
          contentType: doc.format || 'longform',
          channelId: channel.id,
          channelName: channel.name,
          seriesName: series.name,
          hasConflict: conflictEventIds.has(doc.id as number),
          assignedTo: doc.assignedTo,
        },
      }
    })

    return NextResponse.json({
      events,
      conflicts,
      meta: {
        totalEvents: events.length,
        conflictsCount: conflicts.length,
      },
    })
  } catch (error) {
    console.error('[Calendar API] GET error:', error)
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Internal Server Error' },
      { status: 500 },
    )
  }
}

/**
 * PATCH /api/youtube/calendar
 *
 * Reschedules a content item via drag & drop.
 * Body: { contentId: number, newDate: string (ISO) }
 */
export async function PATCH(req: NextRequest): Promise<NextResponse> {
  try {
    const payload = await getPayload({ config })
    const { user } = await payload.auth({ headers: req.headers })

    if (!user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const body = (await req.json()) as { contentId?: number; newDate?: string }
    const { contentId, newDate } = body

    if (!contentId || !newDate) {
      return NextResponse.json({ error: 'contentId and newDate required' }, { status: 400 })
    }

    const content = await payload.findByID({
      collection: 'youtube-content',
      id: contentId,
      depth: 0,
    })

    const status = (content as unknown as Record<string, unknown>).status as string
    if (status === 'published' || status === 'tracked') {
      return NextResponse.json(
        { error: 'Veröffentlichte Videos können nicht verschoben werden' },
        { status: 400 },
      )
    }

    await payload.update({
      collection: 'youtube-content',
      id: contentId,
      data: {
        scheduledPublishDate: newDate,
      },
    })

    return NextResponse.json({
      success: true,
      contentId,
      newDate,
    })
  } catch (error) {
    console.error('[Calendar API] PATCH error:', error)
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Internal Server Error' },
      { status: 500 },
    )
  }
}
