import { z } from "zod";

const fuelTypeEnum = z.enum(["regular", "premium", "diesel", "e85", "electric"]);
const operatingHoursDaySchema = z.object({
  closed: z.boolean().optional().default(true),
  open: z.string().max(20).optional(),
  close: z.string().max(20).optional(),
});
const operatingHoursSchema = z
  .object({
    monday: operatingHoursDaySchema.optional(),
    tuesday: operatingHoursDaySchema.optional(),
    wednesday: operatingHoursDaySchema.optional(),
    thursday: operatingHoursDaySchema.optional(),
    friday: operatingHoursDaySchema.optional(),
    saturday: operatingHoursDaySchema.optional(),
    sunday: operatingHoursDaySchema.optional(),
  })
  .optional();

export const registerGasStationSchema = z.object({
  name: z.string().min(1, "Name is required").max(200),
  address: z.string().min(1, "Address is required").max(500),
  city: z.string().max(100).optional().default(""),
  state: z.string().max(100).optional().default(""),
  zip: z.string().max(20).optional().default(""),
  country: z.string().max(100).optional().default(""),
  phone: z.string().max(30).optional().default(""),
  lat: z.coerce.number().min(-90).max(90),
  lng: z.coerce.number().min(-180).max(180),
  googlePlaceId: z.string().max(255).optional(),
  fuelTypes: z.array(fuelTypeEnum).min(1, "Select at least one fuel type").optional(),
  operatingHours: operatingHoursSchema,
  // Accept either full URL or uploaded local path like /uploads/file.jpg
  mainImage: z.union([z.string().min(1), z.literal("")]).optional().transform((v) => (v === "" ? undefined : v)),
  logoUrl: z.union([z.string().min(1), z.literal("")]).optional().transform((v) => (v === "" ? undefined : v)),
  galleryImages: z.array(z.string().min(1)).optional().default([]),
});

/** Gas station registration with email/password (no auth token required) */
export const registerGasStationWithAccountSchema = registerGasStationSchema.extend({
  email: z.string().email("Valid email is required").max(255),
  password: z.string().min(8, "Password must be at least 8 characters").max(128),
});

export const loginGasStationSchema = z.object({
  email: z.string().email("Valid email is required").max(255),
  password: z.string().min(1, "Password is required").max(128),
});

/** Gas station owner account signup (OTP will be sent to email) */
export const gasStationAccountSignupSchema = z.object({
  email: z.string().email("Valid email is required").max(255),
  password: z.string().min(8, "Password must be at least 8 characters").max(128),
});

/** Verify OTP for gas station owner account */
export const gasStationAccountVerifyOtpSchema = z.object({
  userId: z.string().min(1, "userId is required"),
  otp: z.string().min(4, "otp is required").max(10),
});

/** Resend OTP for gas station account (after signup, before verify) */
export const gasStationResendOtpSchema = z.object({
  userId: z.string().min(1, "userId is required"),
});

/** Forgot password (send OTP) for gas station owner account */
export const gasStationForgotPasswordSchema = z.object({
  email: z.string().email("Valid email is required").max(255),
});

/** Verify OTP before showing reset password screen */
export const gasStationVerifyResetOtpSchema = z.object({
  userId: z.string().min(1, "userId is required"),
  otp: z.string().min(4, "otp is required").max(10),
});

/** Reset password (after verify-reset-otp; no OTP needed again) */
export const gasStationResetPasswordSchema = z
  .object({
    userId: z.string().min(1, "userId is required"),
    password: z.string().min(8, "Password must be at least 8 characters").max(128),
    confirmPassword: z.string().min(1, "Confirm password is required"),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Password and confirm password do not match",
    path: ["confirmPassword"],
  });

/** Update gas station – all fields optional (partial update) */
export const updateGasStationSchema = z.object({
  name: z.string().min(1).max(200).optional(),
  address: z.string().min(1).max(500).optional(),
  city: z.string().max(100).optional(),
  state: z.string().max(100).optional(),
  zip: z.string().max(20).optional(),
  country: z.string().max(100).optional(),
  phone: z.string().max(30).optional(),
  lat: z.coerce.number().min(-90).max(90).optional(),
  lng: z.coerce.number().min(-180).max(180).optional(),
  googlePlaceId: z.string().max(255).optional().nullable(),
  fuelTypes: z.array(fuelTypeEnum).optional(),
  operatingHours: operatingHoursSchema,
  // Accept either full URL or uploaded local path like /uploads/file.jpg
  mainImage: z.union([z.string().min(1), z.literal("")]).optional().transform((v) => (v === "" ? undefined : v)),
  logoUrl: z.union([z.string().min(1), z.literal("")]).optional().transform((v) => (v === "" ? undefined : v)),
  galleryImages: z.array(z.string().min(1)).optional(),
});

/**
 * Stripe Connect onboarding body. Both URLs are optional — when omitted, controllers
 * fall back to the API's own public landing pages (no JWT, sync via `uid`). This avoids
 * the common pitfall of frontends passing an auth-gated page as the `returnUrl`, which
 * loses the JWT during the Stripe → system-browser → app round-trip and shows an
 * "Authentication Required" prompt back on the frontend.
 */
export const connectStripeSchema = z.object({
  returnUrl: z
    .string()
    .url("returnUrl must be a valid URL")
    .optional()
    .or(z.literal("").transform(() => undefined)),
  refreshUrl: z
    .string()
    .url("refreshUrl must be a valid URL")
    .optional()
    .or(z.literal("").transform(() => undefined)),
});

export type RegisterGasStationInput = z.infer<typeof registerGasStationSchema>;
export type RegisterGasStationWithAccountInput = z.infer<typeof registerGasStationWithAccountSchema>;
export type UpdateGasStationInput = z.infer<typeof updateGasStationSchema>;
export type LoginGasStationInput = z.infer<typeof loginGasStationSchema>;
export type GasStationAccountSignupInput = z.infer<typeof gasStationAccountSignupSchema>;
export type GasStationAccountVerifyOtpInput = z.infer<typeof gasStationAccountVerifyOtpSchema>;
export type GasStationResendOtpInput = z.infer<typeof gasStationResendOtpSchema>;
export type GasStationForgotPasswordInput = z.infer<typeof gasStationForgotPasswordSchema>;
export type GasStationVerifyResetOtpInput = z.infer<typeof gasStationVerifyResetOtpSchema>;
export type GasStationResetPasswordInput = z.infer<typeof gasStationResetPasswordSchema>;
export type ConnectStripeInput = z.infer<typeof connectStripeSchema>;

export const gasStationsAlongRouteQuerySchema = z.object({
  startLat: z.coerce.number().min(-90).max(90),
  startLng: z.coerce.number().min(-180).max(180),
  endLat: z.coerce.number().min(-90).max(90),
  endLng: z.coerce.number().min(-180).max(180),
  bufferKm: z.coerce.number().positive().max(20).default(2),
});
