import dotenv from 'dotenv'
dotenv.config()

import { postgresAdapter } from '@payloadcms/db-postgres'
import sharp from 'sharp'
import path from 'path'
import { buildConfig, PayloadRequest } from 'payload'
import { fileURLToPath } from 'url'
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'

import { Media } from './collections/Media'
import { Pages } from './collections/Pages'
import { Users } from './collections/Users'
import { AuditLogs } from './collections/AuditLogs'
import { SharedLayouts } from './collections/SharedLayouts'
import { SharedCTAs } from './collections/SharedCTAs'
import { Footer } from './Footer/config'
import { Header } from './Header/config'
import { plugins } from './plugins'
import { getServerSideURL } from './utilities/getURL'
import { gcsConfig } from './utilities/gcsConfig'
import {
  FixedToolbarFeature,
  HeadingFeature,
  InlineToolbarFeature,
  lexicalEditor,
} from '@payloadcms/richtext-lexical'
import { gcsStorage } from '@payloadcms/storage-gcs'
import { Scripts } from './globals/Scripts/config'
import { formSubmissionsExportEndpoint } from './endpoints/formSubmissionsExport'
import { healthCheckEndpoint } from './endpoints/healthCheck'

const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)

const corsOrigins = [
  getServerSideURL(),
  ...(process.env.PAYLOAD_CORS ? process.env.PAYLOAD_CORS.split(',') : []),
]
  .map((value) => value.trim())
  .filter(Boolean)

const sendgridKey = process.env.SENDGRID_API_KEY
const sendgridFrom = process.env.SMTP_FROM
const sendgridFromName = process.env.EMAIL_FROM_NAME || 'Marketing'
const hasSendgridConfig = Boolean(sendgridKey && sendgridFrom)

export default buildConfig({
  admin: {
    meta: {
      titleSuffix: '- Marketing CMS',
      icons: {
        icon: [{ url: '/kg-icon.png' }],
      },
    },
    components: {
      // The `BeforeLogin` component renders a message that you see while logging into your admin panel.
      // Feel free to delete this at any time. Simply remove the line below.
      beforeLogin: ['@/components/BeforeLogin'],
      graphics: {
        Icon: '@/components/AdminIcon',
        Logo: '@/components/AdminLoginLogo',
      },
      // The `BeforeDashboard` component renders the 'welcome' block that you see after logging into your admin panel.
      // Feel free to delete this at any time. Simply remove the line below.
      beforeDashboard: ['@/components/BeforeDashboard'],
      afterDashboard: ['@/components/DashboardFooter'],
      logout: {
        Button: '@/components/LogoutButton',
      },
      providers: ['@/components/PasswordToggleProvider'],
    },
    importMap: {
      baseDir: path.resolve(dirname),
    },
    user: Users.slug,
    livePreview: {
      breakpoints: [
        {
          label: 'Mobile',
          name: 'mobile',
          width: 375,
          height: 667,
        },
        {
          label: 'Tablet',
          name: 'tablet',
          width: 768,
          height: 1024,
        },
        {
          label: 'Desktop',
          name: 'desktop',
          width: 1440,
          height: 900,
        },
      ],
    },
  },
  db: postgresAdapter({
    pool: {
      connectionString: process.env.DATABASE_URL || '',
      ssl: {
        rejectUnauthorized: false,
      },
    },
    push: false,
  }),
  collections: [Pages, Media, Users, AuditLogs, SharedLayouts, SharedCTAs],
  endpoints: [formSubmissionsExportEndpoint, healthCheckEndpoint],
  cors: corsOrigins,
  csrf: corsOrigins,
  globals: [Header, Footer, Scripts],
  plugins: [
    gcsStorage({
      bucket: gcsConfig.bucket,
      options: {
        projectId: process.env.GCS_PROJECT_ID || 'reflected-disk-450809-k7',
        keyFilename: path.resolve(dirname, '../gcs-credentials.json'),
      },
      collections: {
        media: {
          disableLocalStorage: true,
          generateFileURL: ({ filename, prefix }) => {
            const normalizedPrefix = prefix || gcsConfig.prefix
            return `https://storage.googleapis.com/${gcsConfig.bucket}/${normalizedPrefix}/${filename}`
          },
          prefix: gcsConfig.prefix,
        },
      },
    }),
    ...plugins,
  ],
  secret: process.env.PAYLOAD_SECRET || '',
  email: hasSendgridConfig
    ? nodemailerAdapter({
        defaultFromAddress: sendgridFrom as string,
        defaultFromName: sendgridFromName,
        transportOptions: {
          host: 'smtp.sendgrid.net',
          port: 587,
          auth: {
            user: 'apikey',
            pass: sendgridKey as string,
          },
        },
      })
    : undefined,
  sharp,
  typescript: {
    outputFile: path.resolve(dirname, 'payload-types.ts'),
  },
  jobs: {
    access: {
      run: ({ req }: { req: PayloadRequest }): boolean => {
        // Allow logged in users to execute this endpoint (default)
        if (req.user) return true

        const secret = process.env.CRON_SECRET
        if (!secret) return false

        // If there is no logged in user, then check
        // for the Vercel Cron secret to be present as an
        // Authorization header:
        const authHeader = req.headers.get('authorization')
        return authHeader === `Bearer ${secret}`
      },
    },
    tasks: [],
  },
  editor: lexicalEditor({
    features: ({ rootFeatures }) => {
      return [
        ...rootFeatures,
        HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
        FixedToolbarFeature(),
        InlineToolbarFeature(),
      ]
    },
  }),
})
