import { z } from 'zod'
import type {
  CarplaceHomepageContent,
  CarplaceHomepageHowItWorksStep,
  CarplaceHomepageMetric,
  CarplaceHomepagePillar,
  CarplaceHomepageSectionType,
  CarplaceHomepageStep,
  CarplaceHomepageTestimonial,
} from '@rentaldrivego/types'

export const loginSchema = z.object({
  email:     z.string().email().max(255).trim().toLowerCase(),
  password:  z.string().max(128),
  totpCode:  z.string().length(6).optional(),
  recoveryCode: z.string().min(8).max(32).optional(),
})

export const forgotPasswordSchema = z.object({
  email: z.string().email().max(255).trim().toLowerCase(),
})

export const resetPasswordSchema = z.object({
  token:    z.string().min(1),
  password: z.string().min(8).max(128),
})

export const totpVerifySchema = z.object({
  code: z.string().length(6),
})

export const companiesQuerySchema = z.object({
  q:        z.string().optional(),
  status:   z.string().optional(),
  plan:     z.string().optional(),
  page:     z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(100).default(20),
})

export const rentersQuerySchema = z.object({
  q:        z.string().optional(),
  blocked:  z.string().optional(),
  page:     z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(100).default(20),
})

export const auditLogQuerySchema = z.object({
  adminId:   z.string().optional(),
  action:    z.string().optional(),
  companyId: z.string().optional(),
  entityId:  z.string().optional(),
  page:      z.coerce.number().int().min(1).default(1),
  pageSize:  z.coerce.number().int().min(1).max(100).default(50),
})

export const notificationsQuerySchema = z.object({
  channel:   z.string().optional(),
  status:    z.string().optional(),
  companyId: z.string().optional(),
  page:      z.coerce.number().int().min(1).default(1),
  pageSize:  z.coerce.number().int().min(1).max(200).default(50),
})

export const billingQuerySchema = z.object({
  q:        z.string().optional(),
  status:   z.string().optional(),
  plan:     z.string().optional(),
  page:     z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(100).default(20),
})

export const invoicesQuerySchema = z.object({
  page:     z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(100).default(20),
})

export const permissionSchema = z.object({
  resource: z.enum(['COMPANIES', 'COMPANY_EMPLOYEES', 'SUBSCRIPTIONS', 'PAYMENTS', 'OFFERS', 'RENTERS', 'ADMIN_USERS', 'AUDIT_LOGS', 'PLATFORM_METRICS']),
  actions:  z.array(z.enum(['READ', 'CREATE', 'UPDATE', 'DELETE', 'SUSPEND', 'IMPERSONATE'])).min(1),
})

export const createAdminSchema = z.object({
  email:       z.string().email().trim().toLowerCase(),
  firstName:   z.string().min(1).max(100).trim(),
  lastName:    z.string().min(1).max(100).trim(),
  role:        z.enum(['SUPER_ADMIN', 'ADMIN', 'SUPPORT', 'FINANCE', 'VIEWER']),
  password:    z.string().min(8),
  permissions: z.array(permissionSchema).optional(),
})

export const updateAdminSchema = z.object({
  email: z.string().email().trim().toLowerCase().optional(),
  firstName: z.string().min(1).max(100).trim().optional(),
  lastName: z.string().min(1).max(100).trim().optional(),
  role: z.enum(['SUPER_ADMIN', 'ADMIN', 'SUPPORT', 'FINANCE', 'VIEWER']).optional(),
  password: z.string().min(8).optional(),
  isActive: z.boolean().optional(),
})

export const adminRoleSchema = z.object({
  role: z.enum(['SUPER_ADMIN', 'ADMIN', 'SUPPORT', 'FINANCE', 'VIEWER']),
})

export const adminPermissionsSchema = z.object({
  permissions: z.array(permissionSchema),
})

export const companyStatusSchema = z.object({
  status: z.enum(['ACTIVE', 'SUSPENDED', 'CANCELLED']),
  reason: z.string().optional(),
})

const nullableString = z.union([z.string(), z.null()]).optional()
const nullableEmail  = z.union([z.string().email(), z.null()]).optional()
const nullableUrl    = z.union([z.string().url(), z.null()]).optional()
const nullableDate   = z.union([z.string().datetime(), z.string().regex(/^\d{4}-\d{2}-\d{2}$/), z.null()]).optional()

export const adminCompanyUpdateSchema = z.object({
  company: z.object({
    name: z.string().min(1).optional(), slug: z.string().min(1).optional(),
    email: z.string().email().optional(), phone: nullableString,
    status: z.enum(['PENDING', 'TRIALING', 'ACTIVE', 'PAST_DUE', 'SUSPENDED', 'CANCELLED']).optional(),
    subscriptionPaymentRef: nullableString,
    address: z.object({
      streetAddress: nullableString,
      city: nullableString,
      country: nullableString,
      zipCode: nullableString,
      legalName: nullableString,
      legalForm: nullableString,
      companyEmail: nullableEmail,
      managerName: nullableString,
      iceNumber: nullableString,
      operatingLicenseNumber: nullableString,
      operatingLicenseIssuedAt: nullableString,
      operatingLicenseIssuedBy: nullableString,
      fax: nullableString,
      yearsActive: nullableString,
      representativeName: nullableString,
      representativeTitle: nullableString,
      responsibleName: nullableString,
      responsibleRole: nullableString,
      responsibleIdentityNumber: nullableString,
      responsibleQualification: nullableString,
      responsiblePhone: nullableString,
      responsibleEmail: nullableEmail,
    }).optional(),
  }).optional(),
  subscription: z.object({
    plan: z.enum(['STARTER', 'GROWTH', 'PRO']).optional(),
    billingPeriod: z.enum(['MONTHLY', 'ANNUAL']).optional(),
    status: z.enum(['TRIALING', 'ACTIVE', 'PAST_DUE', 'CANCELLED', 'UNPAID']).optional(),
    currency: z.literal('MAD').optional(),
    trialStartAt: nullableDate, trialEndAt: nullableDate,
    currentPeriodStart: nullableDate, currentPeriodEnd: nullableDate,
    cancelledAt: nullableDate, cancelAtPeriodEnd: z.boolean().optional(),
  }).optional(),
  brand: z.object({
    displayName: z.string().min(1).optional(), tagline: nullableString,
    subdomain: z.string().min(1).optional(), customDomain: nullableString,
    publicEmail: nullableEmail, publicPhone: nullableString, publicAddress: nullableString,
    publicCity: nullableString, publicCountry: nullableString, websiteUrl: nullableUrl,
    whatsappNumber: nullableString, defaultLocale: z.string().min(2).optional(),
    defaultCurrency: z.literal('MAD').optional(),
    isListedOnCarplace: z.boolean().optional(),
    homePageConfig: z.any().optional(),
    menuConfig: z.any().optional(),
  }).optional(),
  contractSettings: z.object({
    legalName: nullableString, registrationNumber: nullableString, taxId: nullableString,
    terms: z.string().optional(),
    fuelPolicyType: z.enum(['FULL_TO_FULL', 'FULL_TO_EMPTY', 'SAME_TO_SAME', 'PREPAID', 'FREE']).optional(),
    lateFeePerHour: z.number().int().nullable().optional(), taxRate: z.number().nullable().optional(),
    signatureRequired: z.boolean().optional(), showTax: z.boolean().optional(),
  }).optional(),
  accountingSettings: z.object({
    reportingPeriod: z.enum(['WEEKLY', 'MONTHLY', 'QUARTERLY', 'ANNUAL']).optional(),
    fiscalYearStart: z.number().int().min(1).max(12).optional(),
    currency: z.literal('MAD').optional(),
    accountantEmail: nullableEmail, accountantName: nullableString,
    autoSendReport: z.boolean().optional(),
    reportFormat: z.enum(['PDF', 'CSV', 'BOTH']).optional(),
  }).optional(),
})

const carplaceMetricSchema:         z.ZodType<CarplaceHomepageMetric>         = z.object({ value: z.string().min(1), label: z.string().min(1) })
const carplacePillarSchema:         z.ZodType<CarplaceHomepagePillar>         = z.object({ title: z.string().min(1), body: z.string().min(1) })
const carplaceStepSchema:           z.ZodType<CarplaceHomepageStep>           = z.object({ step: z.string().min(1), title: z.string().min(1), body: z.string().min(1) })
const carplaceHowItWorksStepSchema: z.ZodType<CarplaceHomepageHowItWorksStep> = z.object({ number: z.string().min(1), title: z.string().min(1), description: z.string().min(1) })
const carplaceTestimonialSchema:    z.ZodType<CarplaceHomepageTestimonial>     = z.object({ quote: z.string().min(1), author: z.string().min(1), role: z.string().min(1), company: z.string().optional() })
const carplaceSectionSchema: z.ZodType<CarplaceHomepageSectionType>  = z.enum(['hero', 'surface', 'pillars', 'audiences', 'features', 'howitworks', 'steps', 'testimonials', 'closing'])

const carplaceHomepageContentSchema: z.ZodType<CarplaceHomepageContent> = z.object({
  sections: z.array(carplaceSectionSchema).min(1),
  heroKicker: z.string().min(1), heroTitle: z.string().min(1), heroBody: z.string().min(1),
  startTrial: z.string().min(1), exploreVehicles: z.string().min(1),
  surfaceLabel: z.string().min(1), surfaceTitle: z.string().min(1), surfaceBody: z.string().min(1),
  liveLabel: z.string().min(1), trustedFleets: z.string().min(1), brandedFlows: z.string().min(1), multiTenant: z.string().min(1),
  companyKicker: z.string().min(1), companyTitle: z.string().min(1), companyBody: z.string().min(1),
  renterKicker: z.string().min(1), renterTitle: z.string().min(1), renterBody: z.string().min(1),
  pillars: z.array(carplacePillarSchema).length(3),
  metrics: z.array(carplaceMetricSchema).length(3),
  featureLabel: z.string().min(1), features: z.array(z.string().min(1)).min(1),
  howitworksKicker: z.string().min(1), howitworksTitle: z.string().min(1), howitworksSteps: z.array(carplaceHowItWorksStepSchema).min(1),
  stepsTitle: z.string().min(1), steps: z.array(carplaceStepSchema).length(3), stepLabel: z.string().min(1),
  testimonialsKicker: z.string().min(1), testimonialsTitle: z.string().min(1), testimonials: z.array(carplaceTestimonialSchema).min(1),
  readyKicker: z.string().min(1), readyTitle: z.string().min(1), readyBody: z.string().min(1),
  viewPricing: z.string().min(1), createWorkspace: z.string().min(1),
})

export const carplaceHomepageConfigSchema = z.object({
  en: carplaceHomepageContentSchema,
  fr: carplaceHomepageContentSchema,
  ar: carplaceHomepageContentSchema,
})

export const idParamSchema = z.object({
  id: z.string().min(1),
})

export const companyIdParamSchema = z.object({
  companyId: z.string().min(1),
})

export const billingAccountIdParamSchema = z.object({
  billingAccountId: z.string().min(1),
})

export const invoiceIdParamSchema = z.object({
  invoiceId: z.string().min(1),
})

export const billingAccountUpdateSchema = z.object({
  legalName: z.string().min(1).max(255).optional(),
  billingEmail: z.string().email().optional(),
  billingAddress: z.any().optional(),
  taxId: z.union([z.string().max(120), z.null()]).optional(),
  taxExempt: z.boolean().optional(),
  invoiceTerms: z.enum(['DUE_ON_RECEIPT', 'NET_7', 'NET_15', 'NET_30', 'NET_45', 'NET_60']).optional(),
  netTermsDays: z.number().int().min(0).max(365).optional(),
})

export const billingLineItemInputSchema = z.object({
  type: z.enum([
    'SUBSCRIPTION_FEE',
    'SEAT_FEE',
    'USAGE_FEE',
    'SETUP_FEE',
    'DISCOUNT',
    'TAX',
    'CREDIT',
    'PRORATION',
    'REFUND_ADJUSTMENT',
    'MANUAL_ADJUSTMENT',
    'PROFESSIONAL_SERVICES',
    'CANCELLATION_FEE',
  ]),
  description: z.string().min(1).max(255),
  quantity: z.number().int().positive().max(100000),
  unitAmount: z.number().int(),
  periodStart: nullableDate,
  periodEnd: nullableDate,
})

export const createBillingInvoiceSchema = z.object({
  subscriptionId: z.union([z.string(), z.null()]).optional(),
  invoiceType: z.enum([
    'SUBSCRIPTION_INITIAL',
    'SUBSCRIPTION_RENEWAL',
    'TRIAL_CONVERSION',
    'SUBSCRIPTION_UPGRADE',
    'SUBSCRIPTION_DOWNGRADE_CREDIT',
    'USAGE_BASED',
    'ONE_TIME',
    'MANUAL',
    'CORRECTION',
    'CANCELLATION_FEE',
  ]),
  currency: z.string().min(3).max(8).optional(),
  dueAt: nullableDate,
  isSubscriptionBlocking: z.boolean().optional(),
  adminReason: z.union([z.string().max(500), z.null()]).optional(),
  lineItems: z.array(billingLineItemInputSchema).min(1),
})

export const payBillingInvoiceSchema = z.object({
  amount: z.number().int().positive().optional(),
  paymentMethodId: z.union([z.string(), z.null()]).optional(),
  providerPaymentId: z.union([z.string(), z.null()]).optional(),
})

export const retryBillingInvoiceSchema = z.object({
  paymentMethodId: z.union([z.string(), z.null()]).optional(),
})

export const billingReasonSchema = z.object({
  reason: z.string().min(1).max(500),
})

export const billingCreditNoteSchema = z.object({
  amount: z.number().int().positive(),
  reason: z.string().min(1).max(500),
})

export const billingRefundSchema = z.object({
  amount: z.number().int().positive(),
  reason: z.string().min(1).max(500),
})

export const homepageUpdateSchema = z.object({
  homepage: carplaceHomepageConfigSchema,
})

export const pricingUpdateSchema = z.object({
  entries: z.array(z.object({
    plan:          z.enum(['STARTER', 'GROWTH', 'PRO']),
    billingPeriod: z.enum(['MONTHLY', 'ANNUAL']),
    amount:        z.number().int().positive(),
  })).min(1),
})

const planFeatureSchema = z.object({
  plan:      z.enum(['STARTER', 'GROWTH', 'PRO']),
  label:     z.string().min(1).max(120),
  sortOrder: z.number().int().min(0).default(0),
})

export const planFeatureCreateSchema = planFeatureSchema
export const planFeatureUpdateSchema = planFeatureSchema.partial()
export const promotionCreateSchema = z.object({
  code:          z.string().min(2).max(30).regex(/^[A-Z0-9_-]+$/, 'Code must be uppercase A-Z, 0-9, _ or -'),
  name:          z.string().min(1).max(100),
  description:   z.string().max(500).optional(),
  discountType:  z.enum(['PERCENTAGE', 'FIXED']),
  discountValue: z.number().int().positive(),
  plans:         z.array(z.enum(['STARTER', 'GROWTH', 'PRO'])),
  periods:       z.array(z.enum(['MONTHLY', 'ANNUAL'])),
  maxUses:       z.number().int().positive().nullable().optional(),
  validFrom:     z.string().datetime(),
  validUntil:    z.string().datetime().nullable().optional(),
  isActive:      z.boolean().default(true),
})

export const promotionUpdateSchema = promotionCreateSchema.partial()

export const planFeatureIdParamSchema = z.object({ featureId: z.string().min(1) })
export const promotionIdParamSchema = z.object({ promotionId: z.string().min(1) })

const employeeRoleSchema = z.enum(['OWNER', 'MANAGER', 'AGENT'])
const planSchema = z.enum(['STARTER', 'GROWTH', 'PRO'])
const menuItemTypeSchema = z.enum(['INTERNAL_PAGE', 'EXTERNAL_LINK', 'PARENT_MENU', 'SECTION_LABEL', 'DIVIDER'])

export const menuItemSchema = z.object({
  systemKey: z.string().trim().min(1).max(120).optional().nullable(),
  label: z.string().trim().min(1).max(120),
  itemType: menuItemTypeSchema,
  routeOrUrl: z.string().trim().max(400).optional().nullable(),
  icon: z.string().trim().max(120).optional().nullable(),
  parentId: z.string().trim().min(1).optional().nullable(),
  displayOrder: z.number().int().min(0).default(0),
  openInNewTab: z.boolean().default(false),
  isRequired: z.boolean().default(false),
  isActive: z.boolean().default(true),
  roles: z.array(employeeRoleSchema).default([]),
  subscriptionPlans: z.array(z.object({
    plan: planSchema,
    displayOrder: z.number().int().min(0).optional(),
    isActive: z.boolean().optional(),
  })).default([]),
  companyAssignments: z.array(z.object({
    companyId: z.string().trim().min(1),
    displayOrder: z.number().int().min(0).optional(),
    isActive: z.boolean().optional(),
  })).default([]),
})

export const menuItemStatusSchema = z.object({
  isActive: z.boolean(),
})

export const menuPlanAssignmentsSchema = z.object({
  assignments: z.array(z.object({
    plan: planSchema,
    displayOrder: z.number().int().min(0).optional(),
    isActive: z.boolean().optional(),
  })).min(1),
})

export const menuCompanyAssignmentsSchema = z.object({
  assignments: z.array(z.object({
    companyId: z.string().trim().min(1),
    displayOrder: z.number().int().min(0).optional(),
    isActive: z.boolean().optional(),
  })).min(1),
})

export const menuPreviewSchema = z.object({
  companyId: z.string().trim().min(1),
  role: employeeRoleSchema,
})

export const menuAuditLogQuerySchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(100).default(20),
})

export const menuItemIdParamSchema = z.object({
  id: z.string().min(1),
})

export const menuPlanParamSchema = z.object({
  id: z.string().min(1),
  plan: planSchema,
})

export const menuCompanyParamSchema = z.object({
  id: z.string().min(1),
  companyId: z.string().min(1),
})
