import { z } from 'zod'
import type { ModuleId } from '@zync/modules'

export const onboardingBusinessTypeEnum = z.enum(['osek_morshe', 'company_ltd', 'osek_patur'])

export const ONBOARDING_MODULE_SLUGS = [
  'crm',
  'customers',
  'time-management',
  'projects',
  'tasks',
  'invoices',
  'expenses',
  'billing',
  'calendar',
  'marketing',
  'knowledge-base',
  'contractor-payouts',
] as const

export const SLUG_TO_MODULE_ID: Record<(typeof ONBOARDING_MODULE_SLUGS)[number], ModuleId> = {
  crm: 'crm',
  customers: 'customers',
  'time-management': 'time_management',
  projects: 'projects',
  tasks: 'tasks',
  invoices: 'invoices',
  expenses: 'expenses',
  billing: 'billing',
  calendar: 'calendar',
  marketing: 'marketing',
  'knowledge-base': 'kb',
  'contractor-payouts': 'contractor_payouts',
}

export interface OnboardingState {
  onboarding_completed: boolean
  onboarding_step: number // 0–5
  data: {
    business_info: {
      business_name?: string
      business_type?: 'osek_morshe' | 'company_ltd' | 'osek_patur'
      tax_id?: string
      logo_url?: string
      phone?: string
      address?: string
    }
    modules: Record<string, boolean> // 12 user-facing slugs
    email_adapter: 'smtp' | 'skip' | null
    invites_sent: number
  }
}

export const onboardingProgressSchema = z.discriminatedUnion('step', [
  z.object({
    step: z.literal(1),
    complete: z.literal(false).optional(),
    data: z.object({
      business_name: z.string().min(1),
      business_type: onboardingBusinessTypeEnum,
      tax_id: z.string().min(1),
      logo_url: z.string().url().optional(),
      phone: z.string().optional(),
      address: z.string().optional(),
    }),
  }),
  z.object({
    step: z.literal(2),
    complete: z.literal(false).optional(),
    data: z.object({ modules: z.record(z.string(), z.boolean()) }),
  }),
  z.object({
    step: z.literal(3),
    complete: z.literal(false).optional(),
    data: z
      .object({
        email_adapter: z.enum(['smtp', 'skip']),
        smtp: z
          .object({
            host: z.string().min(1),
            port: z.number().int().min(1).max(65535),
            username: z.string().min(1),
            password: z.string().min(1),
          })
          .optional(),
      })
      .superRefine((data, ctx) => {
        if (data.email_adapter === 'smtp' && !data.smtp) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: 'SMTP credentials required when email_adapter is smtp',
            path: ['smtp'],
          })
        }
      }),
  }),
  z.object({
    step: z.literal(4),
    complete: z.literal(false).optional(),
    data: z.object({
      invites_sent: z.number().int().min(0),
      invites: z
        .array(
          z.object({
            email: z.string().email(),
            role: z.enum(['ADMIN', 'MEMBER', 'VIEWER', 'CONTRACTOR']),
          }),
        )
        .optional(),
    }),
  }),
  z.object({
    step: z.literal(5),
    complete: z.literal(true),
    data: z.object({}).strict(),
  }),
])

export type OnboardingProgressBody = z.infer<typeof onboardingProgressSchema>

const MAX_ONBOARDING_LOGO_BYTES = 2 * 1024 * 1024

export const onboardingLogoSchema = z.object({
  filename: z.string().min(1),
  content_type: z.enum(['image/png', 'image/jpeg']),
  file_size_bytes: z
    .number()
    .int()
    .min(1)
    .max(MAX_ONBOARDING_LOGO_BYTES),
})

export const onboardingEmailTestSchema = z.object({
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  username: z.string().min(1),
  password: z.string().min(1),
})
