import { z } from 'zod';

const snowflake = z.string().regex(/^\d{17,20}$/);

export const PremiumTierSchema = z.enum(['FREE', 'PREMIUM']);
export type PremiumTier = z.infer<typeof PremiumTierSchema>;

export const PremiumFeatureKeySchema = z.enum(['tags', 'feeds', 'guildbackup']);
export type PremiumFeatureKey = z.infer<typeof PremiumFeatureKeySchema>;

export const PremiumFeaturesSchema = z.object({
  tags: z.boolean(),
  feeds: z.boolean(),
  guildbackup: z.boolean()
});
export type PremiumFeatures = z.infer<typeof PremiumFeaturesSchema>;

export const PremiumTierConfigSchema = z.object({
  tier: PremiumTierSchema,
  maxTags: z.number().int().min(0).max(10_000),
  maxFeeds: z.number().int().min(0).max(10_000),
  maxBackups: z.number().int().min(0).max(10_000),
  features: PremiumFeaturesSchema
});
export type PremiumTierConfig = z.infer<typeof PremiumTierConfigSchema>;

export const PremiumTierConfigPatchSchema = PremiumTierConfigSchema.omit({ tier: true }).partial().refine(
  (value) => Object.keys(value).length > 0,
  { message: 'At least one field is required' }
);
export type PremiumTierConfigPatch = z.infer<typeof PremiumTierConfigPatchSchema>;

export const DEFAULT_PREMIUM_TIER_CONFIGS: Record<PremiumTier, PremiumTierConfig> = {
  FREE: {
    tier: 'FREE',
    maxTags: 15,
    maxFeeds: 3,
    maxBackups: 2,
    features: { tags: true, feeds: true, guildbackup: true }
  },
  PREMIUM: {
    tier: 'PREMIUM',
    maxTags: 100,
    maxFeeds: 25,
    maxBackups: 25,
    features: { tags: true, feeds: true, guildbackup: true }
  }
};

export const GuildPremiumAssignSchema = z.object({
  guildId: snowflake,
  tier: PremiumTierSchema,
  note: z.string().max(500).nullable().optional(),
  expiresAt: z.string().datetime().nullable().optional()
});
export type GuildPremiumAssign = z.infer<typeof GuildPremiumAssignSchema>;

export const UserPremiumAssignSchema = z.object({
  userId: snowflake,
  tier: PremiumTierSchema,
  note: z.string().max(500).nullable().optional(),
  expiresAt: z.string().datetime().nullable().optional()
});
export type UserPremiumAssign = z.infer<typeof UserPremiumAssignSchema>;

export const PremiumLimitResourceSchema = z.enum(['tags', 'feeds', 'backups']);
export type PremiumLimitResource = z.infer<typeof PremiumLimitResourceSchema>;

export function limitKeyForResource(resource: PremiumLimitResource): 'maxTags' | 'maxFeeds' | 'maxBackups' {
  if (resource === 'tags') return 'maxTags';
  if (resource === 'feeds') return 'maxFeeds';
  return 'maxBackups';
}

export function featureKeyForResource(resource: PremiumLimitResource): PremiumFeatureKey {
  if (resource === 'backups') return 'guildbackup';
  return resource;
}

export function parsePremiumFeatures(raw: unknown): PremiumFeatures {
  const parsed = PremiumFeaturesSchema.safeParse(raw);
  if (parsed.success) {
    return parsed.data;
  }
  return { tags: true, feeds: true, guildbackup: true };
}

export function isAssignmentActive(expiresAt: Date | string | null | undefined, now = new Date()): boolean {
  if (!expiresAt) {
    return true;
  }
  const date = typeof expiresAt === 'string' ? new Date(expiresAt) : expiresAt;
  return date.getTime() > now.getTime();
}
