import { ID, Query, databaseId, tables } from './appwrite';
import { teamRechte } from './permissions';

/**
 * Ein Post ist ein **Slot-Rezept**, kein Freitext-Prompt – nur deshalb ist er
 * überhaupt kopierbar (konzept-bilder-feed.md §3). Die Slots liegen strukturiert
 * in `slots`, damit P19 daraus später Chips ableiten kann, ohne den Prompt im
 * Wortlaut preiszugeben.
 */
export type Slots = {
  kulisse_asset_id?: string;
  person_asset_id?: string;
  produkt_asset_id?: string;
  licht?: string;
  kamera?: string;
  farbe?: string;
  werbetext?: string;
};

export type Post = {
  $id: string;
  brand_id: string;
  folder_id?: string;
  titel?: string;
  user_prompt?: string;
  slots?: string;
  format?: string;
  bild_count?: number;
  status?: 'entwurf' | 'generiert' | 'fehler';
  sichtbarkeit?: 'privat' | 'oeffentlich';
  nische?: string;
};

export const FORMATE = [
  { wert: '1:1', titel: 'Quadrat', erklaerung: 'Feed-Beiträge, Produktkacheln.' },
  { wert: '4:5', titel: 'Hochformat', erklaerung: 'Nimmt im Feed mehr Fläche ein.' },
  { wert: '9:16', titel: 'Story', erklaerung: 'Bildschirmfüllend, für Stories und Reels.' },
] as const;

export type Format = (typeof FORMATE)[number]['wert'];

export async function postsImOrdner(folderId: string): Promise<Post[]> {
  const res = await tables.listRows({
    databaseId,
    tableId: 'posts',
    queries: [Query.equal('folder_id', folderId), Query.orderDesc('$createdAt'), Query.limit(100)],
  });
  return res.rows as unknown as Post[];
}

export async function postsDerMarke(brandId: string): Promise<Post[]> {
  const res = await tables.listRows({
    databaseId,
    tableId: 'posts',
    queries: [Query.equal('brand_id', brandId), Query.orderDesc('$createdAt'), Query.limit(100)],
  });
  return res.rows as unknown as Post[];
}

/**
 * Legt das Rezept an und reiht die Generierungen ein.
 *
 * Der Post entsteht **sofort** mit `status: 'entwurf'`, bevor irgendetwas
 * generiert wird. Das ist Absicht: Generierung ist asynchron, und wer während
 * des Wartens weg navigiert, muss das Ergebnis wiederfinden (app-aufbau.md
 * §2.1). Ohne die Zeile gäbe es nichts, wohin man zurückkehren könnte.
 *
 * Je Bild der Kette eine `jobs`-Zeile. Abgearbeitet werden sie vom
 * Job-Dispatcher mit Server-Key – **nicht** vom Client, denn dafür müsste der
 * Anbieter-Schlüssel ins Bundle.
 */
export async function postAnlegen(
  brandId: string,
  teamId: string,
  daten: {
    folderId: string;
    titel: string;
    prompt: string;
    format: Format;
    bildCount: number;
    slots: Slots;
    nische?: string;
  },
): Promise<Post> {
  const rechte = teamRechte(teamId);

  const post = (await tables.createRow({
    databaseId,
    tableId: 'posts',
    rowId: ID.unique(),
    data: {
      brand_id: brandId,
      folder_id: daten.folderId,
      titel: daten.titel,
      user_prompt: daten.prompt,
      slots: JSON.stringify(daten.slots),
      format: daten.format,
      bild_count: daten.bildCount,
      status: 'entwurf',
      sichtbarkeit: 'privat', // Veröffentlichen ist ein aktiver, eigener Schritt
      kopien_count: 0,
      feed_score: 0,
      ...(daten.nische ? { nische: daten.nische } : {}),
    },
    permissions: rechte,
  })) as unknown as Post;

  for (let i = 0; i < daten.bildCount; i++) {
    await tables.createRow({
      databaseId,
      tableId: 'jobs',
      rowId: ID.unique(),
      data: {
        brand_id: brandId,
        typ: 'bild_gen',
        prompt_template_key: 'P7',
        status: 'wartend',
        refs: JSON.stringify({ post_id: post.$id, position: i + 1 }),
      },
      permissions: rechte,
    });
  }

  return post;
}

export type PostBild = {
  $id: string;
  post_id: string;
  position: number;
  typ: 'motiv' | 'text_overlay';
  storage_file_id?: string;
};

/**
 * Die Bilderketten mehrerer Posts in einer Abfrage – nicht eine je Post.
 * Ein Ordner mit 20 Posts wären sonst 20 Rundreisen für eine Listenansicht.
 */
export async function bilderZuPosts(postIds: string[]): Promise<Map<string, PostBild[]>> {
  const nach = new Map<string, PostBild[]>();
  if (!postIds.length) return nach;

  const res = await tables.listRows({
    databaseId,
    tableId: 'post_images',
    queries: [Query.equal('post_id', postIds), Query.orderAsc('position'), Query.limit(200)],
  });
  for (const b of res.rows as unknown as PostBild[]) {
    const liste = nach.get(b.post_id) ?? [];
    liste.push(b);
    nach.set(b.post_id, liste);
  }
  return nach;
}

export async function postLoeschen(id: string): Promise<void> {
  await tables.deleteRow({ databaseId, tableId: 'posts', rowId: id });
}

export function slotsLesen(post: Post): Slots {
  try {
    return post.slots ? (JSON.parse(post.slots) as Slots) : {};
  } catch {
    return {};
  }
}
