// storage-adapter-import-placeholder
import {
  lexicalEditor,
  BoldFeature,
  InlineToolbarFeature,
  ItalicFeature,
  UnderlineFeature,
  ParagraphFeature,
  HeadingFeature,
  AlignFeature,
  UnorderedListFeature,
  LinkFeature,
  FixedToolbarFeature, UploadFeature,
} from '@payloadcms/richtext-lexical'
import path from 'path'
import { buildConfig } from 'payload'
import { fileURLToPath } from 'url'
import sharp from 'sharp'

import { Users } from './collections/Users'
import { Media } from './collections/Media'
import { Worship } from '@/collections/Worship'
import { Churches } from '@/collections/Churches'
import { de } from '@payloadcms/translations/languages/de'
import { Parish } from '@/collections/Parish'
import { Groups } from '@/collections/Groups'
import { Events } from '@/collections/Events'
import { EventOccurrences } from '@/collections/EventOccurrences'
import { Announcements } from '@/collections/Announcements'
import { Blog } from '@/collections/Blog'
import { Highlight } from '@/collections/Highlight'
import { Documents } from '@/collections/Documents'
import { Locations } from '@/collections/Locations'
import { ContactPerson } from '@/collections/ContactPerson'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { gcsStorage } from '@payloadcms/storage-gcs'
import { PopesPrayerIntentions } from '@/collections/PopesPrayerIntentions'
import { LiturgicalCalendar } from '@/collections/LiturgicalCalendar'
import { Classifieds } from '@/collections/Classifieds'
import { MenuGlobal } from '@/globals/Menu'
import { FooterGlobal } from '@/globals/Footer'
import { Magazine } from '@/collections/Magazine'
import { DonationForms } from '@/collections/DonationForms'
import { Pages } from '@/collections/Pages'
import { Prayers } from '@/collections/Prayers'
import { siteConfig } from '@/config/site'
import { generateRecurringMassesTask } from '@/jobs/generateRecurringMasses'
import { generateEventOccurrencesTask } from '@/jobs/generateEventOccurrences'
import { searchPlugin } from '@payloadcms/plugin-search'
import { hide } from '@/collections/access/admin'

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

export default buildConfig({
  admin: {
    user: Users.slug,
    meta: {
      title: 'Dashboard',
      titleSuffix: `- ${siteConfig.shortName}`
    },
    importMap: {
      baseDir: dirname,
    },
    components: {
      graphics: {
        Logo: {
          path: '/components/Logo/Logo',
          serverProps: {
            withText: true,
            height: 90
          }
        },
        Icon: {
          path: '/components/Logo/Logo',
          serverProps: {
            height: 18
          }
        }
      }
    },
    livePreview: {
      collections: ['blog', 'event', 'group', 'pages', 'parish'],
    },
  },
  collections: [
    Parish,
    Churches,
    Worship,
    PopesPrayerIntentions,
    Announcements,
    LiturgicalCalendar,
    Blog,
    Highlight,
    Events,
    EventOccurrences,
    Classifieds,
    ContactPerson,
    Locations,
    Groups,
    DonationForms,
    Pages,
    Prayers,
    Magazine,
    Documents,
    Media,
    Users,
  ],
  globals: [
    MenuGlobal,
    FooterGlobal,
  ],
  jobs: {
    tasks: [generateRecurringMassesTask, generateEventOccurrencesTask],
    autoRun: [
      {
        // once a day at 03:00 (6-field cron, seconds first)
        cron: '0 0 3 * * *',
        queue: 'default',
        limit: 10,
      },
    ],
    // show jobs in the admin panel
    jobsCollectionOverrides: ({ defaultJobsCollection }) => {
      if (!defaultJobsCollection.admin) {
        defaultJobsCollection.admin = {}
      }

      defaultJobsCollection.admin.hidden = process.env.NODE_ENV === 'production'
      return defaultJobsCollection
    },
    shouldAutoRun: () => process.env.NODE_ENV === 'production',
  },
  graphQL: {
    disable: true
  },
  editor: lexicalEditor(
    {
      features: () => [
        BoldFeature(),
        ItalicFeature(),
        UnderlineFeature(),
        HeadingFeature({ enabledHeadingSizes: ["h3","h4","h5"]}),
        AlignFeature(),
        UnorderedListFeature(),
        UploadFeature({
            enabledCollections: ['media']
        }
        ),
        LinkFeature({
          fields: ({ defaultFields }) => [
            ...defaultFields,
            {
              name: 'appearance',
              type: 'select',
              defaultValue: 'link',
              label: 'Darstellung',
              options: [
                { label: 'Link', value: 'link' },
                { label: 'Button', value: 'button' },
              ],
            },
          ],
        }),
        ParagraphFeature(),
        InlineToolbarFeature(),
        FixedToolbarFeature()
      ]
    }
  ),
  secret: process.env.PAYLOAD_SECRET || '',
  typescript: {
    outputFile: path.resolve(dirname, 'payload-types.ts'),
  },
  i18n: {
    supportedLanguages: { de },
  },
  db: postgresAdapter({
    idType: "uuid",
    push: false,
    pool: {
      connectionString: process.env.DATABASE_URI,
    }
  }),
  sharp,
  plugins: [
    gcsStorage({
      enabled: !!process.env.GOOGLE_BUCKET,
      alwaysInsertFields: true,
      collections: {
        media: {
          disablePayloadAccessControl: true,
          prefix: 'media/',
          generateFileURL: (args) =>
            `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/media/${args.filename}`,
        },
        documents: {
          disablePayloadAccessControl: true,
          prefix: 'documents/',
          generateFileURL: (args) =>
            `https://storage.googleapis.com/${process.env.GOOGLE_BUCKET}/documents/${args.filename}`,
        },
      },
      bucket: process.env.GOOGLE_BUCKET || '',
      options: {},
      acl: undefined,
    }),
    searchPlugin({
      collections: ['parish', 'pages', 'blog', 'event', 'group'],
      defaultPriorities: {
        parish: 10,
        pages: 15,
        group: 20,
        event: 30,
        blog: 40,
      },
      // The plugin only reads `title` from the source doc, but Parish and
      // Group use `name` instead. Map `name` → `title` so those collections
      // get an indexed, searchable title.
      beforeSync: ({ originalDoc, searchDoc }) => ({
        ...searchDoc,
        title: originalDoc.title || originalDoc.name || searchDoc.title || '',
      }),
      // The plugin hardcodes `maxDepth: 0` on the polymorphic `doc` field,
      // so `doc.value` is always returned as a string ID — even with depth>0
      // at query time. We need it populated so the search results page can
      // read each referenced document's `slug` to build URLs like
      // /gemeinde/[slug] and /gruppe/[slug].
      searchOverrides: {
        labels: {
          singular: {
            de: 'Suchergebnis',
          },
          plural: {
            de: 'Suchergebnisse',
          },
        },
        admin: {
          hidden: hide,
          description: {
            de: 'Automatisch erzeugte Suchergebnisse. Sie werden von der Website-Suche verwendet und aktualisieren sich selbst, sobald Inhalte erstellt oder geändert werden.',
          },
        },
        fields: ({ defaultFields }) =>
          defaultFields.map((field) =>
            'name' in field && field.name === 'doc' && field.type === 'relationship'
              ? { ...field, maxDepth: 1 }
              : field,
          ),
      },
    })
  ],
})
