import { link } from "fs";
import { ProductStatus } from "../types/types";
import mongooseModel from "mongoose";
import { toImageUrls } from "../utils/imageUrl";
const mongoose = require("mongoose");

const Product = mongoose.Schema(
  {
    title: {
      type: String,
      default: "",
      required: true,
    },
    description: {
      type: String,
      default: "",
      required: false,
    },
    category: {
      type: String,
      default: "other",
      required: false,
    },
    price: {
      type: Number,
      default: 0,
      required: true,
    },
    discountedPrice: {
      type: Number,
      default: null,
      required: false,
    },
    images: {
      type: Array<string>,
      default: "",
      required: true,
    },
    isFeatured: {
      type: Boolean,
      default: false,
      required: false,
    },
    colorVariations: {
      type: Array<string>,
      default: [],
      required: false,
    },
    sizeVariations: {
      type: Array<string>,
      default: [],
      required: false,
    },
    outOfStockVariants: {
      type: [
        {
          color: { type: String, required: true },
          size: { type: String, required: true },
          _id: false,
        },
      ],
      default: [],
      required: false,
    },
    vendor: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    status: {
      type: String,
      default: "Inactive",
      enum: ProductStatus,
      required: false,
    },
    link: {
      type: String,
      default: "",
      required: false,
    },
    orders: {
      type: Number,
      default: 0,
    },
    orderMinDays: {
      type: Number,
      default: 0,
    },
    orderMaxDays: {
      type: Number,
      default: 365,
    },
    weight: {
      type: Number,
      default: 0,
      required: false,
      // Weight in grams
    },
    length: {
      type: Number,
      default: 0,
      required: false,
      // Length in inches
    },
    width: {
      type: Number,
      default: 0,
      required: false,
      // Width in inches
    },
    height: {
      type: Number,
      default: 0,
      required: false,
      // Height in inches
    },
    availableStates: {
      type: Array<string>,
      default: [],
      required: false,
    },
    isDeleted: {
      type: Boolean,
      default: false,
      required: false,
    },
    avgRating: {
      type: Number,
      default: 0,
      required: false,
      // literal mean of this product's own review ratings
    },
    reviewCount: {
      type: Number,
      default: 0,
      required: false,
    },
    weightedRating: {
      type: Number,
      default: 0,
      required: false,
      // Bayesian-adjusted rating (blends avgRating with the store-wide average,
      // weighted by reviewCount) so a product with very few reviews isn't
      // dragged to an extreme by a single outlier review
    },
  },
  { timestamps: true }
);

Product.virtual("storeInfo", {
  ref: "StoreInformation",
  localField: "vendor",
  foreignField: "vendorID",
  justOne: true,
});

// Ensure virtuals appear in JSON / Object, and expand stored S3 keys back
// into full public URLs so callers never have to think about image storage.
const expandImageUrls = (_doc: any, ret: any) => {
  if (ret.images) ret.images = toImageUrls(ret.images);
  return ret;
};
Product.set("toObject", { virtuals: true, transform: expandImageUrls });
Product.set("toJSON", { virtuals: true, transform: expandImageUrls });

Product.pre("find", function (this: mongooseModel.Model<any>) {
  this.populate("vendor", []);
});
Product.pre("findOne", function (this: mongooseModel.Model<any>) {
  this.populate("vendor", []);
});

export default mongoose.model("Product", Product);
