import { NextRequest, NextResponse } from 'next/server';
import { getDb } from '@/lib/db';
import { getAuthenticatedAdmin } from '@/lib/admin-auth';
import { ensureRestaurantStats } from '@/lib/restaurant-stats';
import { parseBody, sponsorUpdateSchema } from '@/lib/validation';
import { buildAddressDisplay } from '@/lib/format-address';
import type { SponsoredRestaurantRow } from '@/lib/db-types';

// NEU: GET fuer die Kampagnen-Detailseite (app/admin/dashboard/sponsors/[id]).
// Nutzt denselben restaurant_stats-LEFT-JOIN wie die Liste in
// app/api/admin/sponsors/route.ts, damit beide Ansichten garantiert
// identische Zahlen zeigen.
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const admin = await getAuthenticatedAdmin();
  if (!admin) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });

  const { id } = await params;
  const db = getDb();
  ensureRestaurantStats(db);

  const sponsor = db.prepare(`
    SELECT
      sr.*,
      COALESCE(rs.impressions, 0) AS impressions,
      COALESCE(rs.yes_swipes, 0) AS yesSwipes,
      COALESCE(rs.matches, 0) AS matches
    FROM sponsored_restaurants sr
    LEFT JOIN restaurant_stats rs ON rs.restaurant_id = sr.restaurant_id
    WHERE sr.id = ?
  `).get(id) as
    | (SponsoredRestaurantRow & { impressions: number; yesSwipes: number; matches: number })
    | undefined;

  if (!sponsor) return NextResponse.json({ error: 'Eintrag nicht gefunden' }, { status: 404 });

  let trend: { day: string; impressions: number; yes_swipes: number; matches: number }[] = [];
  if (sponsor.restaurant_id) {
    trend = db
      .prepare(
        `SELECT day, impressions, yes_swipes, matches
         FROM restaurant_stats_daily
         WHERE restaurant_id = ? AND day >= date('now', '-30 days')
         ORDER BY day ASC`
      )
      .all(sponsor.restaurant_id) as typeof trend;
  }

  return NextResponse.json({ sponsor, trend });
}

export async function PATCH(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const admin = await getAuthenticatedAdmin();
  if (!admin) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });

  const { id } = await params;
  const parsed = await parseBody(req, sponsorUpdateSchema);
  if (!parsed.success) return parsed.response;

  const {
    name, imageUrl, address, city, postalCode, lat, lon,
    filterCuisineTags, discountText, priority,
    active, activeFrom, activeUntil,
    disclaimerText, openingHoursRaw, reservationUrl,
    lieferandoUrl,
    restaurantId,
  } = parsed.data;

  const db = getDb();
  const existing = db.prepare('SELECT * FROM sponsored_restaurants WHERE id = ?').get(id) as
    SponsoredRestaurantRow | undefined;
  if (!existing) return NextResponse.json({ error: 'Eintrag nicht gefunden' }, { status: 404 });

  const resolveString = (incoming: string | null | undefined, current: string | null) =>
    incoming !== undefined ? incoming : current;

  const nextRestaurantId = restaurantId === undefined ? existing.restaurant_id : restaurantId;

  db.prepare(
    `UPDATE sponsored_restaurants SET
       name = ?, image_url = ?, address = ?, city = ?, postal_code = ?, lat = ?, lon = ?,
       filter_cuisine_tags = ?, discount_text = ?, priority = ?, active = ?,
       active_from = ?, active_until = ?, disclaimer_text = ?, opening_hours_raw = ?,
       reservation_url = ?, lieferando_url = ?, restaurant_id = ?
     WHERE id = ?`
  ).run(
    resolveString(name, existing.name),
    resolveString(imageUrl, existing.image_url),
    resolveString(address, existing.address),
    resolveString(city, existing.city),
    resolveString(postalCode, existing.postal_code),
    lat !== undefined ? lat : existing.lat,
    lon !== undefined ? lon : existing.lon,
    filterCuisineTags === undefined
      ? existing.filter_cuisine_tags
      : filterCuisineTags
        ? JSON.stringify(filterCuisineTags)
        : null,
    resolveString(discountText, existing.discount_text),
    priority === undefined ? existing.priority : (priority ?? 0),
    active === undefined ? existing.active : (active ? 1 : 0),
    resolveString(activeFrom, existing.active_from),
    resolveString(activeUntil, existing.active_until),
    resolveString(disclaimerText, existing.disclaimer_text),
    resolveString(openingHoursRaw, existing.opening_hours_raw),
    resolveString(reservationUrl, existing.reservation_url),
    resolveString(lieferandoUrl, existing.lieferando_url),
    nextRestaurantId,
    id
  );

  // Wenn der Sponsor mit einem Restaurant verknuepft ist, Adresse/PLZ etc.
  // im restaurants-Eintrag ebenfalls aktualisieren, damit Matches/Polls die
  // gleiche formatierte Adresse wie die Swipe-Karte zeigen.
  const linkedRestaurantId = nextRestaurantId ?? existing.restaurant_id;
  if (linkedRestaurantId) {
    const nextName = name !== undefined ? name : existing.name;
    const nextAddress = address !== undefined ? address : existing.address;
    const nextCity = city !== undefined ? city : existing.city;
    const nextPostalCode = postalCode !== undefined ? postalCode : existing.postal_code;
    const nextLat = lat !== undefined ? lat : existing.lat;
    const nextLon = lon !== undefined ? lon : existing.lon;
    const nextImageUrl = imageUrl !== undefined ? imageUrl : existing.image_url;
    const nextCuisine = filterCuisineTags === undefined
      ? undefined
      : (filterCuisineTags ? filterCuisineTags.join(', ') : null);
    const nextOpeningHours = openingHoursRaw !== undefined ? openingHoursRaw : undefined;

    db.prepare(`
      UPDATE restaurants SET
        name = ?, lat = ?, lon = ?, address = ?, postal_code = ?,
        admin_image_url = COALESCE(?, admin_image_url),
        image_source_used = CASE WHEN ? IS NOT NULL THEN 'admin' ELSE image_source_used END,
        cuisine = COALESCE(?, cuisine),
        opening_hours_raw = COALESCE(?, opening_hours_raw)
      WHERE id = ?
    `).run(
      nextName,
      nextLat,
      nextLon,
      buildAddressDisplay(nextAddress, nextPostalCode, nextCity),
      nextPostalCode,
      nextImageUrl,
      nextImageUrl,
      nextCuisine,
      nextOpeningHours,
      linkedRestaurantId
    );
  }

  return NextResponse.json({ success: true });
}

export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const admin = await getAuthenticatedAdmin();
  if (!admin) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });

  const { id } = await params;
  const db = getDb();
  db.prepare('DELETE FROM sponsored_restaurants WHERE id = ?').run(id);
  return NextResponse.json({ success: true });
}
