import { RoutingMethod } from '@/constants/websiteBuilder'
import { z } from 'zod'

// Reserved subdomain names
const reservedSubdomains = ['www', 'admin', 'api', 'support', 'mail']
const subdomainRegex = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/ // lowercase, hyphenated, no special chars
const phoneSchema = z.object({
  phone: z
    .number({ invalid_type_error: 'Phone number must be a number' })
    .refine((num) => num.toString().length === 10, {
      message: 'Phone number must be between 7 and 15 digits',
    }),
  countryCode: z
    .number({ invalid_type_error: 'Country code must be a number' })
    .refine(
      (code) => code.toString().length >= 1 && code.toString().length <= 4,
      {
        message: 'Invalid country code',
      }
    ),
})

export const subdomainSchema = z.object({
  template: z.string({ message: 'Please select a template' }),
  company: z
    .string({ message: 'Company name is required' })
    .nonempty({ message: 'Please enter a company name' }),
  companyName: z
    .string({ message: 'Company name is required' })
    .nonempty({ message: 'Please enter a company name' }),
  subdomainName: z
    .string({ message: 'Enter valid Subdomain name' })
    .min(3, { message: 'Subdomain must be at least 3 characters' })
    .max(63, { message: 'Subdomain cannot exceed 63 characters' })
    .regex(subdomainRegex, {
      message:
        'Subdomain must be alphanumeric or hyphens only, no special characters',
    })
    .refine((val) => !reservedSubdomains.includes(val), {
      message: 'Subdomain name is reserved',
    }),
})

export const leadRoutingSchema = z
  .object({
    template: z.string({ message: 'Please select a template' }),
    userId: z.string().optional(), // will validate conditionally
    teamId: z.string().optional(), // will validate conditionally
    leadRoutingType: z.enum(
      Object.values(RoutingMethod) as [string, ...string[]],
      {
        message: 'Please select a lead routing method',
      }
    ),
    leadRoutingUserId: z
      .string({ message: 'Please select a lead routing user' })
      .optional(),
    leadNotifyAdmin: z
      .boolean({ message: 'Please select a lead routing user' })
      .optional(),
  })
  .superRefine((data, ctx) => {
    if (
      data.leadRoutingType === RoutingMethod.specificUser &&
      (!data.userId || data.userId.trim() === '')
    ) {
      ctx.addIssue({
        path: ['userId'],
        code: z.ZodIssueCode.custom,
        message: 'Please select a user',
      })
    }

    if (
      data.leadRoutingType === RoutingMethod.team &&
      (!data.teamId || data.teamId.trim() === '')
    ) {
      ctx.addIssue({
        path: ['teamId'],
        code: z.ZodIssueCode.custom,
        message: 'Please select a team',
      })
    }
  })

// Alternative approach - create a base schema without optional
const baseMobileNumberSchema = z
  .string()
  .optional()
  .refine(
    (val) => {
      // If no value provided, it's valid (optional)
      if (!val || val.trim() === '') {
        return true
      }
      // If value provided, must be exactly 10 digits
      return /^\d{10}$/.test(val.trim())
    },
    {
      message: 'Please enter a valid 10-digit mobile number',
    }
  )
  .transform((val) => {
    // Transform to number if valid, otherwise return undefined
    if (!val || val.trim() === '') {
      return undefined
    }
    const trimmed = val.trim()
    return /^\d{10}$/.test(trimmed) ? Number(trimmed) : undefined
  })

export const websiteSchema = z
  .object({
    template: z
      .string({ message: 'Please select a template' })
      .nonempty({ message: 'Please select a template' }),
    subdomainName: z
      .string({ message: 'Please enter subdomain name' })
      .nonempty({ message: 'Please enter subdomain name' }),
    contactNumber: baseMobileNumberSchema.optional(),
    whatsappNumber: baseMobileNumberSchema.optional(),
    heroBannerTitle: z
      .string({ message: 'Please Enter banner title' })
      .nonempty({ message: 'Please Enter banner title' }),
    heroBannerDesc: z
      .string({ message: 'Please enter banner description' })
      .nonempty({ message: 'Please enter banner description' }),
    bannerImg: z
      .string({ message: 'Please upload image' })
      .nonempty({ message: 'Please upload image' }),
    companyLogo: z
      .string({ message: 'Please upload logo' })
      .nonempty({ message: 'Please upload logo' }),
    aboutTitle: z
      .string({ message: 'Please Enter about title' })
      .nonempty({ message: 'Please Enter about title' }),
    aboutDesc: z
      .string({ message: 'Please enter about description' })
      .nonempty({ message: 'Please enter about description' }),
    aboutImg: z
      .string({ message: 'Please upload image' })
      .nonempty({ message: 'Please upload image' }),
    isPublished: z.boolean({ message: 'Please select status' }),
    serviceTitle: z
      .string({ message: 'Please enter about service title' })
      .nonempty({ message: 'Please enter about service title' }),
    serviceDesc: z
      .string({ message: 'Please enter about service description' })
      .nonempty({ message: 'Please enter about service description' }),
  })
  .refine(
    (data) => {
      console.log('data ====>', data)
      return data.contactNumber || data.whatsappNumber
    },
    {
      message: 'At least one number is required',
      path: ['contactNumber'], // or whatsappNumber based on your preference
    }
  )

export const WebsiteBuilderRootSchema = z.object({
  template: z.string({ message: 'Please select a template' }),
  draftTemplateId: z.string({ message: 'Please select a template' }),
  company: z.string({ message: 'Please select a company' }),
  subdomainName: z.string().nullable(),
})

export type ActiveTab = 'templates' | 'domain' | 'leads' | 'websiteInfo'

export const schemaMap = {
  templates: WebsiteBuilderRootSchema,
  domain: subdomainSchema,
  leads: leadRoutingSchema,
  websiteInfo: websiteSchema,
} as const

// Generic function to get schema
export function getSchema<T extends ActiveTab>(tab: T): (typeof schemaMap)[T] {
  return schemaMap[tab]
}

// Export schema type for a specific tab if needed
export type SchemaByTab = {
  [K in ActiveTab]: z.infer<(typeof schemaMap)[K]>
}
