import { z } from 'zod';
import {
  dateTransformSchema,
  defaultTransformSchema,
  nullableDefaultTransformSchema,
} from '../shared/shared.dto';

const optionalString = z.preprocess((value) => {
  if (typeof value === 'string' && value.trim() === '') return undefined;
  return value;
}, z.string().trim().optional());

export const requestDeviceChangeSchema = z.object({
  device_id: z.string().min(1, 'Device ID/fingerprint is required').trim(),
  device_name: optionalString,
  reason: z.string().min(1, 'Reason for device change is required').trim(),
});

export const reviewDeviceChangeSchema = z.object({
  status: z.enum(['approved', 'rejected'], {
    message: 'Status must be approved or rejected',
  }),
  admin_note: optionalString,
});

export const deviceChangeFilterSchema = z.object({
  status: z.enum(['pending', 'approved', 'rejected', 'all']).optional(),
  member_id: z.string().uuid().optional(),
});

export const teacherDeviceResponseSchema = z.object({
  id: z.string().uuid(),
  member_id: z.string().uuid(),
  device_id: z.string(),
  device_name: nullableDefaultTransformSchema,
  last_ip: nullableDefaultTransformSchema,
  bound_at: dateTransformSchema,
  last_active_at: z
    .date()
    .nullable()
    .transform((d) => (d ? d.toISOString() : null))
    .optional(),
  member: z
    .object({
      id: z.string().uuid(),
      first_name: z.string(),
      last_name: defaultTransformSchema,
      employee_id: z.string(),
      work_email: z.string().optional(),
    })
    .optional(),
  created_at: dateTransformSchema,
  updated_at: dateTransformSchema,
});

export const deviceChangeRequestResponseSchema = z.object({
  id: z.string().uuid(),
  member_id: z.string().uuid(),
  owner_id: z.string(),
  old_device_id: z.string(),
  new_device_id: z.string(),
  new_device_name: nullableDefaultTransformSchema,
  reason: nullableDefaultTransformSchema,
  status: z.enum(['pending', 'approved', 'rejected']),
  reviewed_by_id: nullableDefaultTransformSchema,
  reviewed_at: z
    .date()
    .nullable()
    .transform((d) => (d ? d.toISOString() : null))
    .optional(),
  admin_note: nullableDefaultTransformSchema,
  member: z
    .object({
      id: z.string().uuid(),
      first_name: z.string(),
      last_name: defaultTransformSchema,
      employee_id: z.string(),
      work_email: z.string().optional(),
    })
    .optional(),
  created_at: dateTransformSchema,
  updated_at: dateTransformSchema,
});

export const deviceChangeRequestListSchema = z.array(
  deviceChangeRequestResponseSchema,
);

export type RequestDeviceChangeDto = z.infer<typeof requestDeviceChangeSchema>;
export type ReviewDeviceChangeDto = z.infer<typeof reviewDeviceChangeSchema>;
export type DeviceChangeFilterDto = z.infer<typeof deviceChangeFilterSchema>;
export type TeacherDeviceResponseDto = z.infer<typeof teacherDeviceResponseSchema>;
export type DeviceChangeRequestResponseDto = z.infer<
  typeof deviceChangeRequestResponseSchema
>;
