import { NextRequest, NextResponse } from 'next/server'
import OpenAI from 'openai'
import { getPayload } from 'payload'
import config from '@payload-config'

/**
 * Analyzes a meal order form image using OpenAI Vision API
 * Extracts selected meal options from the photographed paper form
 */

// Define the expected structure of extracted meal data
interface BreakfastData {
  accordingToPlan?: boolean
  bread?: {
    breadRoll?: boolean
    wholeGrainRoll?: boolean
    greyBread?: boolean
    wholeGrainBread?: boolean
    whiteBread?: boolean
    crispbread?: boolean
  }
  porridge?: boolean
  preparation?: {
    sliced?: boolean
    spread?: boolean
  }
  spreads?: {
    butter?: boolean
    margarine?: boolean
    jam?: boolean
    diabeticJam?: boolean
    honey?: boolean
    cheese?: boolean
    quark?: boolean
    sausage?: boolean
  }
  beverages?: {
    coffee?: boolean
    tea?: boolean
    hotMilk?: boolean
    coldMilk?: boolean
  }
  additions?: {
    sugar?: boolean
    sweetener?: boolean
    coffeeCreamer?: boolean
  }
}

interface LunchData {
  portionSize?: 'small' | 'large' | 'vegetarian'
  soup?: boolean
  dessert?: boolean
  specialPreparations?: {
    pureedFood?: boolean
    pureedMeat?: boolean
    slicedMeat?: boolean
    mashedPotatoes?: boolean
  }
  restrictions?: {
    noFish?: boolean
    fingerFood?: boolean
    onlySweet?: boolean
  }
}

interface DinnerData {
  accordingToPlan?: boolean
  bread?: {
    greyBread?: boolean
    wholeGrainBread?: boolean
    whiteBread?: boolean
    crispbread?: boolean
  }
  preparation?: {
    spread?: boolean
    sliced?: boolean
  }
  spreads?: {
    butter?: boolean
    margarine?: boolean
  }
  soup?: boolean
  porridge?: boolean
  noFish?: boolean
  beverages?: {
    tea?: boolean
    cocoa?: boolean
    hotMilk?: boolean
    coldMilk?: boolean
  }
  additions?: {
    sugar?: boolean
    sweetener?: boolean
  }
}

interface AnalysisResult {
  mealType: 'breakfast' | 'lunch' | 'dinner'
  residentName?: string
  roomNumber?: string
  highCaloric?: boolean
  aversions?: string
  notes?: string
  breakfast?: BreakfastData
  lunch?: LunchData
  dinner?: DinnerData
  confidence: number
  rawAnalysis?: string
}

const getSystemPrompt = (mealType?: string) => {
  const basePrompt = `You are an expert at analyzing meal order forms from elderly care homes.
Your task is to look at a photo of a paper meal order form and extract all the checked/marked options.
The form may be in ANY language (German, English, or other). Look for visual indicators like:
- Checkmarks (✓, ✗, X)
- Filled circles or boxes
- Handwritten marks
- Any indication that an option is selected

IMPORTANT: Return ONLY a JSON object with the EXACT structure shown below. Set boolean fields to true ONLY if they are clearly marked/checked on the form.`

  if (mealType === 'breakfast') {
    return `${basePrompt}

You MUST return this EXACT JSON structure for breakfast:
{
  "mealType": "breakfast",
  "confidence": <number 0-100>,
  "breakfast": {
    "accordingToPlan": <boolean>,
    "bread": {
      "breadRoll": <boolean>,
      "wholeGrainRoll": <boolean>,
      "greyBread": <boolean>,
      "wholeGrainBread": <boolean>,
      "whiteBread": <boolean>,
      "crispbread": <boolean>
    },
    "porridge": <boolean>,
    "preparation": {
      "sliced": <boolean>,
      "spread": <boolean>
    },
    "spreads": {
      "butter": <boolean>,
      "margarine": <boolean>,
      "jam": <boolean>,
      "diabeticJam": <boolean>,
      "honey": <boolean>,
      "cheese": <boolean>,
      "quark": <boolean>,
      "sausage": <boolean>
    },
    "beverages": {
      "coffee": <boolean>,
      "tea": <boolean>,
      "hotMilk": <boolean>,
      "coldMilk": <boolean>
    },
    "additions": {
      "sugar": <boolean>,
      "sweetener": <boolean>,
      "coffeeCreamer": <boolean>
    }
  }
}

Common terms to look for (in any language):
- Bread roll / Brötchen / Roll
- Whole grain / Vollkorn
- Grey bread / Graubrot
- White bread / Weißbrot
- Crispbread / Knäckebrot
- Porridge / Brei / Oatmeal
- Sliced / geschnitten / cut
- Spread / geschmiert / buttered
- Butter, Margarine, Jam/Konfitüre, Honey/Honig, Cheese/Käse, Quark, Sausage/Wurst
- Coffee/Kaffee, Tea/Tee, Hot milk/Milch heiß, Cold milk/Milch kalt
- Sugar/Zucker, Sweetener/Süßstoff, Coffee creamer/Kaffeesahne`
  }

  if (mealType === 'lunch') {
    return `${basePrompt}

You MUST return this EXACT JSON structure for lunch:
{
  "mealType": "lunch",
  "confidence": <number 0-100>,
  "lunch": {
    "portionSize": <"small" | "large" | "vegetarian" | null>,
    "soup": <boolean>,
    "dessert": <boolean>,
    "specialPreparations": {
      "pureedFood": <boolean>,
      "pureedMeat": <boolean>,
      "slicedMeat": <boolean>,
      "mashedPotatoes": <boolean>
    },
    "restrictions": {
      "noFish": <boolean>,
      "fingerFood": <boolean>,
      "onlySweet": <boolean>
    }
  }
}

Common terms to look for (in any language):
- Small portion / Kleine Portion
- Large portion / Große Portion
- Vegetarian / Vollwertkost vegetarisch
- Soup / Suppe
- Dessert
- Pureed food / passierte Kost
- Pureed meat / passiertes Fleisch
- Sliced meat / geschnittenes Fleisch
- Mashed potatoes / Kartoffelbrei
- No fish / ohne Fisch
- Finger food / Fingerfood
- Only sweet / nur süß`
  }

  if (mealType === 'dinner') {
    return `${basePrompt}

You MUST return this EXACT JSON structure for dinner:
{
  "mealType": "dinner",
  "confidence": <number 0-100>,
  "dinner": {
    "accordingToPlan": <boolean>,
    "bread": {
      "greyBread": <boolean>,
      "wholeGrainBread": <boolean>,
      "whiteBread": <boolean>,
      "crispbread": <boolean>
    },
    "preparation": {
      "spread": <boolean>,
      "sliced": <boolean>
    },
    "spreads": {
      "butter": <boolean>,
      "margarine": <boolean>
    },
    "soup": <boolean>,
    "porridge": <boolean>,
    "noFish": <boolean>,
    "beverages": {
      "tea": <boolean>,
      "cocoa": <boolean>,
      "hotMilk": <boolean>,
      "coldMilk": <boolean>
    },
    "additions": {
      "sugar": <boolean>,
      "sweetener": <boolean>
    }
  }
}

Common terms to look for (in any language):
- According to plan / lt. Plan
- Grey bread / Graubrot
- Whole grain bread / Vollkornbrot
- White bread / Weißbrot
- Crispbread / Knäckebrot
- Spread / geschmiert
- Sliced / geschnitten
- Soup / Suppe
- Porridge / Brei
- No fish / ohne Fisch
- Tea / Tee, Cocoa / Kakao
- Hot milk / Milch heiß, Cold milk / Milch kalt
- Sugar / Zucker, Sweetener / Süßstoff`
  }

  // Generic prompt if meal type is not specified
  return `${basePrompt}

First, determine if this is a breakfast, lunch, or dinner form, then return the appropriate structure.

For BREAKFAST, return:
{
  "mealType": "breakfast",
  "confidence": <number>,
  "breakfast": { /* breakfast options */ }
}

For LUNCH, return:
{
  "mealType": "lunch",
  "confidence": <number>,
  "lunch": { /* lunch options */ }
}

For DINNER, return:
{
  "mealType": "dinner",
  "confidence": <number>,
  "dinner": { /* dinner options */ }
}`
}

export async function POST(request: NextRequest) {
  try {
    // Check for OpenAI API key
    const openaiApiKey = process.env.OPENAI_API_KEY
    if (!openaiApiKey) {
      return NextResponse.json(
        { error: 'OpenAI API key not configured' },
        { status: 500 }
      )
    }

    // Check authentication
    const payload = await getPayload({ config })
    const { user } = await payload.auth({ headers: request.headers })

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

    // Get the image data from the request
    const body = await request.json()
    const { imageUrl, imageBase64, mealType } = body

    if (!imageUrl && !imageBase64) {
      return NextResponse.json(
        { error: 'Image URL or base64 data is required' },
        { status: 400 }
      )
    }

    // Initialize OpenAI client
    const openai = new OpenAI({
      apiKey: openaiApiKey,
    })

    // Prepare the image content for the API
    let imageContent: OpenAI.Chat.ChatCompletionContentPart
    if (imageBase64) {
      imageContent = {
        type: 'image_url',
        image_url: {
          url: `data:image/jpeg;base64,${imageBase64}`,
          detail: 'high',
        },
      }
    } else {
      imageContent = {
        type: 'image_url',
        image_url: {
          url: imageUrl,
          detail: 'high',
        },
      }
    }

    // Call OpenAI Vision API
    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [
        {
          role: 'system',
          content: getSystemPrompt(mealType),
        },
        {
          role: 'user',
          content: [
            {
              type: 'text',
              text: `Analyze this meal order form image. Extract ALL checked/marked options and return the JSON structure exactly as specified. Look carefully for any marks, checks, X's, or filled boxes that indicate a selection.`,
            },
            imageContent,
          ],
        },
      ],
      max_tokens: 2000,
      response_format: { type: 'json_object' },
    })

    const content = response.choices[0]?.message?.content
    if (!content) {
      return NextResponse.json(
        { error: 'No response from vision API' },
        { status: 500 }
      )
    }

    // Parse the response
    let analysisResult: AnalysisResult
    try {
      analysisResult = JSON.parse(content)
    } catch {
      // If JSON parsing fails, return the raw content
      return NextResponse.json({
        mealType: mealType || 'unknown',
        confidence: 0,
        rawAnalysis: content,
        error: 'Could not parse structured response',
      })
    }

    return NextResponse.json(analysisResult)
  } catch (error) {
    console.error('Form analysis error:', error)
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Failed to analyze form' },
      { status: 500 }
    )
  }
}
