import type { Core } from "@strapi/strapi";
import fs from "fs";
import path from "path";

/** Published header for GET /api/nav-layout (Strapi 5 document API; entityService fallback). */
async function loadNavLayoutHeader(
  strapi: Core.Strapi
): Promise<Record<string, unknown> | null> {
  try {
    const doc = await strapi.documents("api::header.header").findFirst({
      status: "published",
      populate: "*",
    } as any);
    return doc as Record<string, unknown>;
  } catch (e: any) {
    strapi.log.warn(
      `[nav-layout] header (documents): ${e?.message || String(e)}`
    );
    try {
      const rows = await strapi.entityService.findMany("api::header.header", {
        populate: "*",
      } as any);
      const row = Array.isArray(rows) ? rows[0] : rows;
      return (row as Record<string, unknown>) ?? null;
    } catch (e2: any) {
      strapi.log.error(
        `[nav-layout] header (entityService): ${e2?.message || String(e2)}`
      );
      return null;
    }
  }
}

/** Published footer for GET /api/nav-layout. */
async function loadNavLayoutFooter(
  strapi: Core.Strapi
): Promise<Record<string, unknown> | null> {
  try {
    const doc = await strapi.documents("api::footer.footer").findFirst({
      status: "published",
      populate: "*",
    } as any);
    return doc as Record<string, unknown>;
  } catch (e: any) {
    strapi.log.warn(
      `[nav-layout] footer (documents): ${e?.message || String(e)}`
    );
    try {
      const rows = await strapi.entityService.findMany("api::footer.footer", {
        populate: {
          logo: { fields: ["url", "alternativeText"] },
          socialMediaLinks: true,
          contactInfo: { populate: ["items"] },
          menuColumns: { populate: ["items"] },
        },
      } as any);
      const row = Array.isArray(rows) ? rows[0] : rows;
      return (row as Record<string, unknown>) ?? null;
    } catch (e2: any) {
      strapi.log.error(
        `[nav-layout] footer (entityService): ${e2?.message || String(e2)}`
      );
      return null;
    }
  }
}

export default {
  /**
   * An asynchronous register function that runs before
   * your application is initialized.
   *
   * This gives you an opportunity to extend code.
   */
  register({ strapi }: { strapi: Core.Strapi }) {
    // CRITICAL: Patch documents.use BEFORE middleware is registered
    try {
      const documentsService = strapi.documents as any;
      if (documentsService && documentsService.use) {
        const originalUse = documentsService.use.bind(documentsService);
        documentsService.use = function(middleware: any) {
          // Block AI localization middleware from being registered
          if (middleware && typeof middleware === 'function') {
            const mwStr = middleware.toString();
            if (mwStr.includes('ai-localizations') || mwStr.includes('generateDocumentLocalizations')) {
              strapi.log.info('[Footer Fix] Blocked AI localization middleware registration');
              return documentsService; // Return service without registering
            }
          }
          return originalUse(middleware);
        };
      }
    } catch (error) {
      // Ignore if documents service not ready
    }
  },

  /**
   * An asynchronous bootstrap function that runs before
   * your application gets started.
   *
   * This gives you an opportunity to set up your data model,
   * run jobs, or perform some special logic.
   */
  async bootstrap({ strapi }: { strapi: Core.Strapi }) {
    (global as any).strapi = strapi;

    // Set permissions for contact forms to allow public access
    try {
      const publicRole = await strapi
        .query("plugin::users-permissions.role")
        .findOne({ where: { type: "public" } });

      if (publicRole) {
        // Safety net: ensure public role cannot hit auth register action
        await strapi
          .query("plugin::users-permissions.permission")
          .deleteMany({
            where: {
              action: "plugin::users-permissions.auth.register",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Ignore if permission does not exist
          });

        // Enable create permission for customer-contact
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::customer-contact.customer-contact.create",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable create permission for land-owner-contact
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::land-owner-contact.land-owner-contact.create",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for contact-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::contact-page.contact-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for footer (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::footer.footer.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for bespoke-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::bespoke-page.bespoke-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for header (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::header.header.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::home-page.home-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable create permission for newsletter-subscription
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action:
                "api::newsletter-subscription.newsletter-subscription.create",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find and findOne permissions for property (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::property.property.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::property.property.findOne",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable create permission for property (for API scripts)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::property.property.create",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for designo-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::designo-page.designo-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for fmd-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::fmd-page.fmd-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for news-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::news-page.news-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find permission for story-page (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::story-page.story-page.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find and findOne permissions for property (to read data)

        // Enable find permission for location (to read data)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::location.location.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        // Enable find and findOne for redirect (public GET only)
        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::redirect.redirect.find",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        await strapi
          .query("plugin::users-permissions.permission")
          .create({
            data: {
              action: "api::redirect.redirect.findOne",
              role: publicRole.id,
            },
          })
          .catch(() => {
            // Permission might already exist, ignore error
          });

        console.log("✅ Contact form permissions configured");
      }
    } catch (error) {
      console.error("❌ Error setting permissions:", error);
    }

    try {
      strapi.server.routes([
        {
          method: "GET",
          path: "/api/nav-layout",
          config: { auth: false },
          handler: async (ctx: any) => {
            try {
              const [header, footer] = await Promise.all([
                loadNavLayoutHeader(strapi),
                loadNavLayoutFooter(strapi),
              ]);

              ctx.set("Content-Type", "application/json");
              ctx.body = {
                data: {
                  header: { data: header },
                  footer: { data: footer },
                },
              };
            } catch (err: any) {
              strapi.log.error("[nav-layout]", err);
              ctx.status = 500;
              ctx.body = { error: "Failed to load nav layout bundle" };
            }
          },
        },
      ]);
      strapi.log.info("Registered GET /api/nav-layout (header + footer bundle)");
    } catch (e) {
      strapi.log.warn("Could not register /api/nav-layout", e);
    }
  },
};
