import { z } from 'zod';
import { ASSET_STATUSES, CATEGORY_KINDS } from '../referentiel';

// ————— Catégories (référentiels administrables) —————

export const CategorySchema = z.object({
  id: z.uuid(),
  kind: z.enum(CATEGORY_KINDS),
  name: z.string(),
  isActive: z.boolean(),
  usageCount: z.number().int(), // appareils ou organes qui l'utilisent
});
export type Category = z.infer<typeof CategorySchema>;

export const CategoriesResponseSchema = z.object({
  categories: z.array(CategorySchema),
});
export type CategoriesResponse = z.infer<typeof CategoriesResponseSchema>;

export const CategoryCreateSchema = z.object({
  kind: z.enum(CATEGORY_KINDS),
  name: z.string().min(1).max(80),
});
export type CategoryCreate = z.infer<typeof CategoryCreateSchema>;

export const CategoryUpdateSchema = z.object({
  name: z.string().min(1).max(80).optional(),
  isActive: z.boolean().optional(), // désactivation — jamais de suppression si utilisé
});
export type CategoryUpdate = z.infer<typeof CategoryUpdateSchema>;

// ————— Emplacements (site → zone) —————

export const LocationSchema = z.object({
  id: z.uuid(),
  name: z.string(),
  parentId: z.uuid().nullable(), // null = site
  address: z.string().nullable(),
  city: z.string().nullable(),
  guardianName: z.string().nullable(),
  guardianPhone: z.string().nullable(),
  latitude: z.number().nullable(),
  longitude: z.number().nullable(),
  partnerId: z.uuid().nullable(), // client/syndic du site (R3 — rattachements Tiers)
  partnerName: z.string().nullable(),
  assetCount: z.number().int(), // appareils rattachés (zones incluses pour un site)
});
export type LocationDto = z.infer<typeof LocationSchema>;

export const LocationsResponseSchema = z.object({
  locations: z.array(LocationSchema), // liste plate — le web construit l'arbre
});
export type LocationsResponse = z.infer<typeof LocationsResponseSchema>;

export const LocationCreateSchema = z.object({
  name: z.string().min(1).max(120),
  parentId: z.uuid().optional(),
  address: z.string().max(200).optional(),
  city: z.string().max(80).optional(),
  guardianName: z.string().max(120).optional(),
  guardianPhone: z.string().max(40).optional(),
  latitude: z.number().min(-90).max(90).optional(),
  longitude: z.number().min(-180).max(180).optional(),
  partnerId: z.uuid().nullable().optional(), // null = détacher le client/syndic
});
export type LocationCreate = z.infer<typeof LocationCreateSchema>;

export const LocationUpdateSchema = LocationCreateSchema.partial();
export type LocationUpdate = z.infer<typeof LocationUpdateSchema>;

// ————— Appareils & organes —————

export const AssetComponentSchema = z.object({
  id: z.uuid(),
  typeId: z.uuid(),
  typeName: z.string(),
  designation: z.string().nullable(),
});
export type AssetComponentDto = z.infer<typeof AssetComponentSchema>;

export const AssetSchema = z.object({
  id: z.uuid(),
  reference: z.string(),
  brand: z.string(),
  model: z.string().nullable(),
  serialNumber: z.string().nullable(),
  commissionedAt: z.iso.datetime().nullable(),
  loadKg: z.number().int().nullable(),
  floors: z.number().int().nullable(),
  status: z.enum(ASSET_STATUSES),
  categoryId: z.uuid(),
  categoryName: z.string(),
  locationId: z.uuid(),
  locationName: z.string(),
  siteName: z.string(), // le site racine (= locationName si rattaché au site)
  componentCount: z.number().int(),
});
export type AssetDto = z.infer<typeof AssetSchema>;

export const AssetsResponseSchema = z.object({ assets: z.array(AssetSchema) });
export type AssetsResponse = z.infer<typeof AssetsResponseSchema>;

/** Option minimale pour désigner un appareil (signalement) — accessible à
 *  tout rôle authentifié : les références sont affichées en cabine. */
export const AssetOptionSchema = z.object({
  id: z.uuid(),
  reference: z.string(),
  siteName: z.string(),
});
export const AssetOptionsResponseSchema = z.object({
  options: z.array(AssetOptionSchema),
});
export type AssetOptionsResponse = z.infer<typeof AssetOptionsResponseSchema>;

export const AssetDetailSchema = AssetSchema.extend({
  components: z.array(AssetComponentSchema),
});
export type AssetDetail = z.infer<typeof AssetDetailSchema>;

export const AssetComponentCreateSchema = z.object({
  typeId: z.uuid(), // Category(kind=COMPONENT_TYPE) — vérifié service
  designation: z.string().max(120).optional(),
});
export type AssetComponentCreate = z.infer<typeof AssetComponentCreateSchema>;

export const AssetCreateSchema = z.object({
  reference: z.string().min(1).max(30),
  brand: z.string().min(1).max(80),
  model: z.string().max(80).optional(),
  serialNumber: z.string().max(80).optional(),
  commissionedAt: z.iso.datetime().optional(),
  loadKg: z.number().int().positive().optional(),
  floors: z.number().int().positive().optional(),
  categoryId: z.uuid(), // Category(kind=EQUIPMENT) — vérifié service
  locationId: z.uuid(),
  components: z.array(AssetComponentCreateSchema).optional(),
});
export type AssetCreate = z.infer<typeof AssetCreateSchema>;

export const AssetUpdateSchema = AssetCreateSchema.omit({ components: true })
  .partial()
  .extend({ status: z.enum(ASSET_STATUSES).optional() });
export type AssetUpdate = z.infer<typeof AssetUpdateSchema>;

// ————— Équipes —————

export const TeamMemberSchema = z.object({
  id: z.uuid(),
  displayName: z.string(),
  roleName: z.string(),
  initials: z.string(),
});

export const TeamSchema = z.object({
  id: z.uuid(),
  name: z.string(),
  description: z.string().nullable(),
  members: z.array(TeamMemberSchema),
});
export type Team = z.infer<typeof TeamSchema>;

export const TeamsResponseSchema = z.object({ teams: z.array(TeamSchema) });
export type TeamsResponse = z.infer<typeof TeamsResponseSchema>;

export const TeamCreateSchema = z.object({
  name: z.string().min(1).max(80),
  description: z.string().max(200).optional(),
  memberIds: z.array(z.uuid()).optional(),
});
export type TeamCreate = z.infer<typeof TeamCreateSchema>;

export const TeamUpdateSchema = TeamCreateSchema.partial();
export type TeamUpdate = z.infer<typeof TeamUpdateSchema>;
