// lib/homepage-content.ts
// Homepage content management — supports both Puck editor data and legacy format
import { db } from '@/lib/db';
import { homepageContent } from '@/shared/schema';
import { eq } from 'drizzle-orm';
import type { Data } from '@puckeditor/core';

const SITE_ID = process.env.SITE_ID || 'ten-sura-game.com';

// Default Puck data — represents the initial homepage layout using site components
export const DEFAULT_PUCK_DATA: Data = {
  content: [
    {
      type: "SiteHeroSection",
      props: {
        id: "site-hero-1",
        dataMode: "auto",
        count: 5,
        autoRotateInterval: 5000,
        showExcerpt: true,
        manualItems: [],
      },
    },
    {
      type: "SiteLatestArticles",
      props: {
        id: "site-latest-1",
        count: 12,
      },
    },
    {
      type: "SiteAllCategorySections",
      props: {
        id: "site-categories-1",
        articlesPerCategory: 4,
      },
    },
    {
      type: "SiteNewsletterSection",
      props: {
        id: "site-newsletter-1",
        title: "最新攻略情報をメールで受け取る",
        description: "新しい攻略記事やイベント情報を週1回お届けします。最新のゲーム情報をいち早くキャッチしましょう！",
        buttonText: "登録する",
        placeholder: "メールアドレスを入力",
      },
    },
  ],
  root: { props: {} },
  zones: {},
};

function applyDefaults(puckData: any) {
  if (!puckData || !puckData.content) return puckData;
  const defaultPropsMap: Record<string, Record<string, any>> = {};
  for (const item of DEFAULT_PUCK_DATA.content) {
    if (item.props?.id) {
      defaultPropsMap[item.props.id] = item.props;
    }
    defaultPropsMap[item.type] = item.props;
  }
  puckData.content = puckData.content.map((item: any) => {
    const defaults = defaultPropsMap[item.props?.id] || defaultPropsMap[item.type] || {};
    return {
      ...item,
      props: { ...defaults, ...item.props },
    };
  });
  return puckData;
}

/**
 * Get homepage content in Puck format with DB retries
 */
export async function getHomepageContent(path: string = '/') {
  const dbSiteId = path === '/' ? SITE_ID : `${SITE_ID}${path}`;
  let retries = 3;
  while (retries > 0) {
    try {
      const rows = await db
        .select()
        .from(homepageContent)
        .where(eq(homepageContent.siteId, dbSiteId))
        .limit(1);

      const dbContent = rows[0]?.content as Record<string, any> | null;
      const dbDraftContent = rows[0]?.draftContent as Record<string, any> | null;

      const livePuckData = dbContent?.puckData as Data | undefined;
      const draftPuckData = dbDraftContent?.puckData as Data | undefined;

      const finalPuckData = livePuckData ? applyDefaults(livePuckData) : (path === '/' ? DEFAULT_PUCK_DATA : null);
      const finalDraftData = draftPuckData ? applyDefaults(draftPuckData) : finalPuckData;

      return { 
        puckData: finalPuckData,
        draftData: finalDraftData
      };
    } catch (error) {
      retries -= 1;
      if (retries === 0) {
        throw new Error("Database failed to respond after 3 attempts.");
      }
      await new Promise(resolve => setTimeout(resolve, 1500));
    }
  }
  return path === '/' 
    ? { puckData: DEFAULT_PUCK_DATA, draftData: DEFAULT_PUCK_DATA }
    : { puckData: null, draftData: null };
}

/**
 * Save homepage content (Puck format) to DB
 */
export async function saveHomepageContent(content: Record<string, any>, updatedBy?: string, mode: 'publish' | 'draft' | 'auto' = 'publish', path: string = '/') {
  const dbSiteId = path === '/' ? SITE_ID : `${SITE_ID}${path}`;
  try {
    const existing = await db
      .select({ id: homepageContent.id })
      .from(homepageContent)
      .where(eq(homepageContent.siteId, dbSiteId))
      .limit(1);

    const updateData: Record<string, any> = {
      updatedAt: new Date(),
      updatedBy: updatedBy || null,
    };

    if (mode === 'publish') {
      updateData.content = content;
      updateData.draftContent = content; // Sync draft with publish
    } else {
      updateData.draftContent = content;
    }

    if (existing.length > 0) {
      await db
        .update(homepageContent)
        .set(updateData)
        .where(eq(homepageContent.siteId, dbSiteId));
    } else {
      await db
        .insert(homepageContent)
        .values({
          siteId: dbSiteId,
          content: mode === 'publish' ? content : {}, // Initial publish uses empty if first save is a draft
          draftContent: content,
          updatedBy: updatedBy || null,
        });
    }

    return { success: true };
  } catch (error) {
    console.error('Error saving homepage content:', error);
    return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
  }
}
