import { defineDocumentType, makeSource } from '@contentlayer/source-files';
import readingTime from 'reading-time';
// support for anchor links
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
// adds rel to external links
import rehypeExternalLinks from 'rehype-external-links';
// support for math
import rehypeKatex from 'rehype-katex';
// support for code syntax highlighting
import rehypePrism from 'rehype-prism-plus';
// adds slug to headings
import rehypeSlug from 'rehype-slug';
// support for github flavored markdown
import remarkGfm from 'remark-gfm';
// support for math
import remarkMath from 'remark-math';
import remarkMdxImages from 'remark-mdx-images';

// adds width and height to images
import rehypeImageSize from './src/plugins/rehype-image-size';

// Blog
export const Post = defineDocumentType(() => ({
	name: 'Post',
	filePathPattern: `apps/landing/posts/**/*.mdx`,
	contentType: 'mdx',
	fields: {
		title: { type: 'string', required: true },
		author: { type: 'string', default: 'Spacedrive Technology Inc.' },
		date: { type: 'date', required: true },
		image: {
			type: 'string',
			description: 'Hero Image URL',
			// TODO: Change this to a generic default image
			default: 'https://avatars.githubusercontent.com/u/101227423?s=200&v=4'
		},
		imageAlt: { type: 'string', description: 'Hero Image Alt' },
		excerpt: { type: 'string' },
		tags: {
			type: 'list',
			of: { type: 'string' },
			required: true
		}
	},
	computedFields: {
		url: {
			type: 'string',
			resolve: (post) => `/blog/${post._raw.sourceFileName.replace(/\.mdx$/, '')}`
		},
		slug: {
			type: 'string',
			resolve: (post) => post._raw.sourceFileName.replace(/\.mdx$/, '')
		},
		readTime: { type: 'string', resolve: (doc) => readingTime(doc.body.raw).text },
		image: {
			type: 'string',
			resolve: (post) => (post.image.startsWith('http') ? post.image : `/${post.image}`)
		}
	}
}));

// Docs
export const Document = defineDocumentType(() => ({
	name: 'Doc',
	filePathPattern: `docs/**/*.mdx`,
	contentType: 'mdx',
	fields: {
		title: {
			type: 'string',
			description: 'Title of the document, if nothing is provided file name will be used'
		},
		description: {
			type: 'string',
			description: 'Used for SEO and social media sharing',
			required: false,
			default: ''
		},
		index: {
			type: 'number',
			default: 100,
			description:
				'Order of the document, if nothing is provided, 100 is default. This is relative to the other docs in the category. Group of lower indexes (categories) will be shown first.'
		}
	},
	computedFields: {
		url: { type: 'string', resolve: (post) => `/${post._raw.flattenedPath}` },
		slug: {
			type: 'string',
			resolve: (p) => p._raw.flattenedPath.replace(/^.+?(\/)/, '')
		},
		title: {
			type: 'string',
			resolve: (p) =>
				p.title
					? toTitleCase(p.title)
					: toTitleCase(
							p._raw.flattenedPath
								.replace(/^.+?(\/)/, '')
								.split('/')
								.slice(-1)[0]
						)
		},
		section: {
			type: 'string',
			resolve: (p) => p._raw.flattenedPath.replace(/^.+?(\/)/, '').split('/')[0]
		},
		category: {
			type: 'string',
			resolve: (p) => p._raw.flattenedPath.replace(/^.+?(\/)/, '').split('/')[1] || ''
		}
	}
}));

export default makeSource({
	contentDirPath: '../../', // project dir
	contentDirInclude: ['docs', 'apps/landing/posts'],
	documentTypes: [Post, Document],
	mdx: {
		remarkPlugins: [
			remarkGfm,
			remarkMath,
			remarkMdxImages // does this even do anything??
		],
		rehypePlugins: [
			[rehypeImageSize, { root: `${process.cwd()}/public` }],
			rehypeSlug,
			rehypeAutolinkHeadings,
			rehypeKatex,
			rehypePrism,
			rehypeExternalLinks
		]
	}
});

// Can't import the one in utils/util.ts so we have to duplicate it here
function toTitleCase(str: string) {
	return str
		.toLowerCase()
		.replace(/(?:^|[\s-/])\w/g, function (match) {
			return match.toUpperCase();
		})
		.replaceAll('-', ' ');
}
