import { CancelToken } from "axios";
import { AvailablePeriod } from "models/availability-calendar/availability-calendar.model";
import { Booking } from "redux/Booking/types";
import { MediaUpload, ListQueryParams, Pagination } from "redux/Common/types";
import { ProductCodeType } from "redux/Product/types";
import { Talent } from "redux/Talent/types";

export type ProductImage = {
  name: string;
  link: string;
  image: string;
  price: string;
};

export type Contents1To1Request = {
  covers?: Array<string>;
  name?: string;
  description?: string;
  duration?: number;
  price?: number;
  interactive?: boolean;

  // for one to one
  availablePeriods?: AvailablePeriod[];
  availablePeriodTimezone?: string;
  talent?: number; // for collaborator talentProfileId = string, userId = number
};

export type PublishExperienceRequest = {
  id: string;
  type: EXPERIENCE_TYPE;
};

export type UpdateExperience1To1Request = {
  requestBody: Contents1To1Request;
  id: string;
};

export type UpdateExperienceRequest = {
  requestBody: { status: EXPERIENCE_STATUS };
  id: string;
};

export type GetExperienceByIdRequest = {
  expId: string;
  cancelToken?: CancelToken;
};

export enum CREATE_EXPERIENCE_STEP {
  PHOTOS_VIDEOS = "1",
  EXPERIENCE_DETAILS = "2",
  AVAILABILITY_TIME = "3",
  CHILD_EXPERIENCE = "3",
  E_COMMERCE = "4",
  PREVIEW = "5",
}

export enum EXPERIENCE_TYPE {
  LIVE_CLASS = "live_class",
  ONE_TO_ONE = "one_to_one",
  EXCLUSIVE_CONTENT = "exclusive_content",
  E_COMMERCE = "e_commerce",
  COURSE = "course",
  SPECIAL_REQUEST = "special_request",
  INTERACTIVE_LIVE_CLASS = "interactive_live_class",
  BUNDLE = "bundle",
}

export const ExperienceTypeLabel = new Map<string, string>([
  [EXPERIENCE_TYPE.LIVE_CLASS, "Broadcast"],
  [EXPERIENCE_TYPE.INTERACTIVE_LIVE_CLASS, "Live Class"],
  [EXPERIENCE_TYPE.ONE_TO_ONE, "1-to-1"],
  [EXPERIENCE_TYPE.EXCLUSIVE_CONTENT, "On-Demand"],
  [EXPERIENCE_TYPE.COURSE, "Course"],
  [EXPERIENCE_TYPE.BUNDLE, "Bundle"],
]);

export enum EXPERIENCE_STATUS {
  DRAFT = "draft",
  PUBLISHED = "published",
  UNPUBLISHED = "unpublished",
  ARCHIVED = "archived",
}

export enum EXPERIENCE_PROCESS_STATUS {
  EMPTY = "EMPTY",
  REQUESTING = "REQUESTING",
  REQUEST_FAIL = "REQUEST_FAIL",
  DRAFTED = "DRAFTED",
  CREATED = "CREATED",
  UPDATED = "UPDATED",
  PUBLISHED = "PUBLISHED",
  COMPLETED = "COMPLETED",
}

export type GetExperiencePayload = {
  type: EXPERIENCE_TYPE;
  params: ListQueryParams;
};

export type UpdateStagingCoversPayload = {
  uploadItemIndex: string;
  photo: Experience["media"];
};

export type TimeRange = {
  id?: string;
  startTime: string;
  endTime: string;
  occurrence: string[];
};

export type DateOff = {
  id?: string;
  date: string;
};

export type StateExperienceLocation = {
  data: Experience;
  contentType: EXPERIENCE_TYPE;
};

export type LessonType = {
  name?: string;
  description?: string;
  video: {
    url?: string;
    metadata?: any;
  };
  order?: number;
};

export type Experience = {
  id?: string;
  bundle?: string;
  media?: MediaUpload[];
  description?: string;
  status?: string;
  name?: string;
  duration?: number;
  rating?: number;
  totalRatings?: number;
  isFreeExperience?: boolean;
  prerequisites?: Array<string>;
  date?: string;
  covers?: Array<string>;
  link?: string;
  attachments?: Array<{
    url: string;
    metadata?: {
      name: string;
      size: number;
    };
  }>;
  tags?: {
    id: number;
    name: string;
  }[];
  type?: EXPERIENCE_TYPE;
  createdAt?: string;
  updatedAt?: string;
  scheduleTime?: string;
  creator?: Talent;
  timeRanges?: TimeRange[];
  dateOffs?: DateOff[];
  video?: string;
  image?: string;
  productSectionTitle?: string;
  products?: {
    id: string;
    image: string;
    link: string;
    name: string;
    price: number;
    codeType: ProductCodeType;
    codes: { code: string }[];
  }[];
  isBooked?: boolean;
  maxAttendees?: number;
  lessons?: LessonType[];
  experiences?: Experience[];
  experienceCreationCurrency?: string;
  gbpExperiencePrice?: number;
  experiencePrice?: number;
  availablePeriods?: AvailablePeriod[];
  availablePeriodTimezone?: string;
  bookings?: Booking[];
};

export type ExperienceState = {
  loading: boolean;
  updatingId?: string;
  updateSuccess?: boolean;
  error?: string | null;
  publishError?: string | null;
  contentProcessStatus: EXPERIENCE_PROCESS_STATUS;
  stagingCovers: { [key in string]: MediaUpload };
  productImages: { [key in string]: MediaUpload };
  lessons: { [key in string]: MediaUpload };
  attachments: { [key in string]: MediaUpload };
  experience: Pagination<Experience[]> | null;
  experienceDetail: Experience | null;
  fetchExperienceDetail: Experience | null;
};
