import {
	type Annotation,
	type Author,
	annotationSchema,
	authorSchema,
	type Book,
	bookSchema,
	type City,
	type Comment,
	type Concept,
	type Contribution,
	type Copyright,
	type Country,
	citySchema,
	commentSchema,
	conceptSchema,
	contributionSchema,
	copyrightSchema,
	countrySchema,
	type Emotion,
	emotionSchema,
	type ReadabilityScore,
	readabilityScoreSchema,
	type Tag,
	type TopicCluster,
	type Translation,
	tagSchema,
	topicClusterSchema,
	translationSchema,
	type User,
	type UserProfile,
	type UserStats,
	userProfileSchema,
	userSchema,
	userStatsSchema,
	type Work,
	type WorkStats,
	type WritingStyle,
	workSchema,
	workStatsSchema,
	writingStyleSchema,
} from "@shared/schema";
import { z } from "zod";

// Extended Zod schemas for frontend-specific types
export const workWithAuthorSchema = workSchema.extend({
	author: authorSchema.optional(),
	tags: z.array(tagSchema).optional(),
	likes: z.number().optional(),
});

// TypeScript types inferred from Zod schemas (defined first to avoid circular references)
export type CommentWithUser = z.infer<typeof commentSchema> & {
	user?: z.infer<typeof userSchema>;
	replies?: CommentWithUser[];
};

export const commentWithUserSchema: z.ZodType<CommentWithUser> =
	commentSchema.extend({
		user: userSchema.optional(),
		replies: z.array(z.lazy(() => commentWithUserSchema)).optional(),
	});

export const workWithDetailsSchema = workWithAuthorSchema.extend({
	translations: z.array(translationSchema).optional(),
	comments: z.array(commentWithUserSchema).optional(),
	readabilityScore: readabilityScoreSchema.optional(),
	writingStyle: writingStyleSchema.optional(),
	emotions: z.array(emotionSchema).optional(),
	concepts: z.array(conceptSchema).optional(),
	topicClusters: z.array(topicClusterSchema).optional(),
	stats: workStatsSchema.optional(),
	copyright: copyrightSchema.optional(),
});

export const translationWithDetailsSchema = translationSchema.extend({
	translator: userSchema.optional(),
	stats: z
		.object({
			id: z.string(),
			views: z.number(),
			createdAt: z.string(),
			updatedAt: z.string().optional(),
			translation: translationSchema,
		})
		.optional(),
	copyright: copyrightSchema.optional(),
});

export const bookmarkWithWorkSchema = z.object({
	id: z.string(),
	userId: z.string(),
	workId: z.string(),
	createdAt: z.string(),
	work: workSchema,
});

export const collectionItemSchema = z.object({
	id: z.string(),
	collectionId: z.string(),
	workId: z.string(),
	order: z.number(),
	addedAt: z.string(),
	work: workSchema,
});

export const collectionWithItemsSchema = z.object({
	id: z.string(),
	name: z.string(),
	slug: z.string(),
	description: z.string().optional(),
	userId: z.string(),
	isPublic: z.boolean(),
	createdAt: z.string(),
	items: z.array(collectionItemSchema),
});

export const authorWithWorksSchema = authorSchema.extend({
	works: z.array(workWithAuthorSchema),
	country: countrySchema.optional(),
	city: citySchema.optional(),
	copyright: copyrightSchema.optional(),
});

export const timelineEventWithAuthorSchema = z.object({
	id: z.string(),
	authorId: z.string(),
	year: z.number(),
	title: z.string(),
	description: z.string().optional(),
	createdAt: z.string(),
	author: authorSchema,
});

export const searchResultsSchema = z.object({
	works: z.array(workSchema),
	authors: z.array(authorSchema),
});

export const filterParamsSchema = z.object({
	language: z.string().optional(),
	type: z.string().optional(),
	yearStart: z.number().optional(),
	yearEnd: z.number().optional(),
	tags: z.array(z.string()).optional(),
});

export const readingContextSchema = z.object({
	workId: z.string(),
	translationId: z.string().optional(),
	progress: z.number(),
	fontSizeClass: z.string(),
	zenMode: z.boolean(),
});

export const annotationWithUserSchema = annotationSchema.extend({
	userName: z.string(),
	userAvatar: z.string().optional(),
	likes: z.number(),
	liked: z.boolean(),
});

export const blogAuthorSchema = z.object({
	id: z.string(),
	displayName: z.string().optional(),
	avatar: z.string().optional(),
});

export const blogPostWithDetailsSchema = z.object({
	id: z.string(),
	title: z.string(),
	slug: z.string(),
	content: z.string(),
	authorId: z.string(),
	excerpt: z.string().optional(),
	publishedAt: z.string().optional(),
	createdAt: z.string(),
	author: userSchema.optional(),
	tags: z.array(tagSchema).optional(),
	commentCount: z.number().optional(),
	likeCount: z.number().optional(),
	comments: z.array(commentWithUserSchema).optional(),
});

// Additional extended schemas using new types
export const userWithProfileSchema = userSchema.extend({
	profile: userProfileSchema.optional(),
	stats: userStatsSchema.optional(),
	country: countrySchema.optional(),
	city: citySchema.optional(),
	contributions: z.array(contributionSchema).optional(),
});

export const bookWithDetailsSchema = bookSchema.extend({
	author: authorSchema.optional(),
	works: z.array(workSchema).optional(),
	copyright: copyrightSchema.optional(),
});

export const contributionWithDetailsSchema = contributionSchema.extend({
	user: userSchema.optional(),
	work: workSchema.optional(),
	translation: translationSchema.optional(),
});

export const blogPostListItemSchema = z.object({
	id: z.string(),
	title: z.string(),
	slug: z.string(),
	excerpt: z.string().optional(),
	publishedAt: z.string().optional(),
	createdAt: z.string(),
	author: blogAuthorSchema.optional(),
	tags: z.array(tagSchema).optional(),
	commentCount: z.number(),
	likeCount: z.number(),
});

// Extended types inferred from Zod schemas
export type WorkWithAuthor = z.infer<typeof workWithAuthorSchema>;
export type WorkWithDetails = z.infer<typeof workWithDetailsSchema>;
export type TranslationWithDetails = z.infer<
	typeof translationWithDetailsSchema
>;
export type BookmarkWithWork = z.infer<typeof bookmarkWithWorkSchema>;
export type CollectionWithItems = z.infer<typeof collectionWithItemsSchema>;
export type AuthorWithWorks = z.infer<typeof authorWithWorksSchema>;
export type TimelineEventWithAuthor = z.infer<
	typeof timelineEventWithAuthorSchema
>;
export type SearchResults = z.infer<typeof searchResultsSchema>;
export type FilterParams = z.infer<typeof filterParamsSchema>;
export type ReadingContext = z.infer<typeof readingContextSchema>;
export type AnnotationWithUser = z.infer<typeof annotationWithUserSchema>;
export type BlogPostWithDetails = z.infer<typeof blogPostWithDetailsSchema>;
export type BlogPostListItem = z.infer<typeof blogPostListItemSchema>;

// New extended types for GraphQL alignment
export type UserWithProfile = z.infer<typeof userWithProfileSchema>;
export type BookWithDetails = z.infer<typeof bookWithDetailsSchema>;
export type ContributionWithDetails = z.infer<
	typeof contributionWithDetailsSchema
>;

// Re-export base types from shared schema
export type {
	User,
	Author,
	Work,
	Translation,
	Tag,
	Comment,
	Annotation,
	Country,
	City,
	Book,
	Copyright,
	Contribution,
	UserProfile,
	ReadabilityScore,
	WritingStyle,
	Emotion,
	Concept,
	TopicCluster,
	WorkStats,
	UserStats,
};
