import { AddressData } from "./common";

export interface ISector {
  id: string;
  code: string;
  name: string;
  description: string;
  createdAt: string;
  updatedAt: string;
  adresse: AddressData;
  agenciesNbr: number;
  agencies?: IAgency[];
}

export interface IAgency {
  id: string;
  name: string;
  description: string;
  adresse: AddressData;
  createdAt: string;
  updatedAt: string;
  departmentsNbr: number;
  sector?: ISector;
  departments?: IDepartment[];
}

export interface IDepartment {
  id: string;
  name: string;
  adresse: AddressData;
  description: string;
  createdAt: string;
  updatedAt: string;
  lotsNbr: number;
  agency?: IAgency;
  lots?: ILot[];
}

export interface ILot {
  id: string;
  name: string;
  lotNumber: string;
  description: string;
  createdAt: string;
  updatedAt: string;
  department?: IDepartment[];
  sourceLots?: ILot[];
}

export type SectorNames = {
  id: number;
  name: string;
};

export type AgencyNames = {
  id: number;
  name: string;
};

export type Agencies = {
};

export type DepartmentNames = {
  id: number;
  name: string;
  zoneId: string;
};

export type LotNumbers = {
  id: number;
  number: string;
};

interface BaseEntity {
  id?: number;
  createdAt?: string;
  updatedAt?: string;
}

export interface Address extends BaseEntity {
  street?: string;
  zipCode?: string;
  city?: string;
  country?: string;
  additionalAddress?: string;
  latitude: number;
  longitude: number;
  addressType?: AddressType;
}

export enum AddressType {
  COLLABORATOR = 'COLLABORATOR',
  CLIENT = 'CLIENT',
  ESTABLISHMENT = 'ESTABLISHMENT',
  REPRESENTATIVE = 'REPRESENTATIVE',
  BANQUE = 'BANQUE',
  DRIVER = 'DRIVER',
  PICKUP = 'PICKUP_ADDRESS'
}

export interface MapAddresse {
  address: string,
  city: string,
  country: string,
  formattedAddress: string,
  lat: number,
  lng: number,
  placeId: string,
  postalCode: string
}

export interface SectorList {
  id: string;
  name: string;
  address?: string;
  createdAt: string;
  active: boolean;
}

export interface SectorPageFilterParams {
  name?: string;
  address?: string;
  createdAt?: string;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}

export interface SectorRequest {
  id: string;
  name: string;
  description: string;
  mapAddresse?: MapAddresse;
}

export interface Sector extends BaseEntity {
  name: string;
  description: string;
  address?: Address;
  agenciesNbr: number;
  agencies: AgencyChildren[];
}

export const mapSectorToSectorRequest = (sector: Sector): SectorRequest => {
  return {
    id: sector.id ? sector.id.toString() : '',
    name: sector.name,
    description: sector.description,
    mapAddresse: mapAddressToMapAddresse(sector.address)
  };
};

export interface AgencyList {
  id: string;
  name: string;
  address?: string;
  description: string;
  createdAt: string;
  active: boolean;
}

export interface AgencyPageFilterParams {
  name?: string;
  address?: string;
  description?: string;
  createdAt?: string;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}

export interface AgencyRequest {
  id: string;
  name: string;
  description: string;
  mapAddresse?: MapAddresse;
  sectorId: string;
}

export interface Agency extends BaseEntity {
  name: string;
  description: string;
  address?: Address;
  sectorId: string;
  departmentsNbr: number;
  departments: DepartmentChildren[];
}

export const mapAgencyToAgencyRequest = (agency: Agency): AgencyRequest => {
  return {
    id: agency.id ? agency.id.toString() : '',
    name: agency.name,
    description: agency.description,
    mapAddresse: mapAddressToMapAddresse(agency.address),
    sectorId: agency.sectorId ? agency.sectorId.toString() : '',
  };
};

export interface DepartmentList {
  id: string;
  name: string;
  code: string;
  address?: string;
  description: string;
  hexColor: string;
  zoneName: string;
  createdAt: string;
  active: boolean;
}

export interface DepartmentPageFilterParams {
  name?: string;
  code?: string;
  address?: string;
  description?: string;
  createdAt?: string;
  zoneName?: string;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}

export interface DepartmentRequest {
  id: string;
  name: string;
  description: string;
  code: string;
  mapAddresse?: MapAddresse;
  hexColor: string;
  agencyId: string;
  zoneId: string;
}

export interface Department extends BaseEntity {
  name: string;
  code: string;
  description: string;
  address?: Address;
  hexColor: string;
  agencyId: string;
  lotsNbr: number;
  lots: LotChildren[];
  zoneId: string;
}

export const mapDepartmentToDepartmentRequest = (department: Department): DepartmentRequest => {
  return {
    id: department.id ? department.id.toString() : '',
    name: department.name,
    code: department.code,
    description: department.description,
    mapAddresse: mapAddressToMapAddresse(department.address),
    hexColor: department.hexColor,
    agencyId: department.agencyId ? department.agencyId.toString() : '',
    zoneId: department.zoneId ? department.zoneId.toString() : '',
  };
};

export interface LotList {
  id: string;
  number: string;
  description: string;
  createdAt: string;
  active: boolean;
}

export interface LotPageFilterParams {
  number?: string;
  description?: string;
  createdAt?: string;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}

export interface LotRequest {
  id: string;
  number: string;
  description: string;
  departmentsIds: string[];
}

export interface Lot extends BaseEntity {
  number: string;
  description: string;
  departmentsIds: string[];
}

export const mapLotToLotRequest = (lot: Lot): LotRequest => {
  return {
    id: lot.id ? lot.id.toString() : '',
    number: lot.number,
    description: lot.description,
    departmentsIds: lot.departmentsIds ? lot.departmentsIds.map(id => id.toString()) : [],
  };
};


export interface SectorWithAgencies extends BaseEntity {
  name?: string;
  description?: string;
  address?: Address;
  agenciesNbr: number;
  active: boolean;
  agencies: AgencyChildren[];
}

export interface AgencyWithDepartments extends BaseEntity {
  name?: string;
  description?: string;
  address?: Address;
  departmentsNbr: number;
  active: boolean;
  departments: DepartmentChildren[];
}

export interface DepartmentWithLots extends BaseEntity {
  name?: string;
  code?: string;
  description?: string;
  address?: Address;
  lotsNbr: number;
  zoneName?: string;
  active: boolean;
  lots: LotChildren[];
}

export interface AgencyChildren extends BaseEntity {
  name?: string;
  description?: string;
  address?: Address;
  departmentsNbr: number;
  sectorId?: number;
  active: boolean;
  archived: boolean;
}

export interface DepartmentChildren extends BaseEntity {
  name?: string;
  code?: string;
  description?: string;
  address?: Address;
  lotsNbr: number;
  agencyId?: number;
  zoneName?: string;
  active: boolean;
  archived: boolean;
}

export interface LotChildren extends BaseEntity {
  number?: string;
  description?: string;
  address?: Address;
  active: boolean;
  archived: boolean;
}

export const mapAddressToMapAddresse = (address?: Address): MapAddresse | undefined => {
  if (!address) return undefined;
  
  const { street, zipCode, city, country } = address;

  const addressParts = [
    street && `${street}`,
    zipCode && `${zipCode}`,
    city && `${city}`,
    country && `${country}`
  ].filter(Boolean).join(", ");

  return {
    address: addressParts,
    lat: address.latitude,
    lng: address.longitude,
    city: city || '',
    postalCode: zipCode || '',
    country: country || '',
    formattedAddress: addressParts,
    placeId: ''
  };
};