import { InferModel } from "drizzle-orm";
import {
  bigserial,
  text,
  timestamp,
  pgTable,
  real,
  pgEnum,
  json,
  boolean,
} from "drizzle-orm/pg-core";

export const MaterialType: [string, ...string[]] = [
  "suspended_floor_insulation",
  "solid_floor_insulation",
  "external_wall_insulation",
  "internal_wall_insulation",
  "cavity_wall_insulation",
  "mechanical_ventilation",
  "loft_insulation",
  "exposed_floor_insulation",
  "flat_roof_insulation",
  "room_roof_insulation",
  "cavity_wall_extraction",
  // Non insulation tasks
  "iwi_wall_demolition",
  "iwi_vapour_barrier",
  "iwi_redecoration",
  "suspended_floor_demolition",
  "suspended_floor_redecoration",
  "suspended_floor_vapour_barrier",
  "solid_floor_demolition",
  "solid_floor_preparation",
  "solid_floor_vapour_barrier",
  "solid_floor_redecoration",
  "ewi_wall_demolition",
  "ewi_wall_preparation",
  "ewi_wall_redecoration",
  "low_energy_lighting_installation",
  "flat_roof_preparation",
  "flat_roof_vapour_barrier",
  "flat_roof_waterproofing",
  // Windows
  "windows_glazing",
  "secondary_glazing",
  "double_glazing",
  // vents
  "trickle_vent",
  "door_undercut",
  // solar
  "solar_pv",
  "solar_battery",
  // scaffolding
  "scaffolding",
  // heating systems
  "high_heat_retention_storage_heaters",
  "air_source_heat_pump",
  // Upgrade an exiting heating system
  "boiler_upgrade",
  // heating controls
  "roomstat_programmer_trvs",
  "time_temperature_zone_control",
  // other
  "sealing_fireplace",
];
export const materialTypeEnum = pgEnum("type", MaterialType);

export const DepthUnit: [string, ...string[]] = ["mm"];
export const depthUnitEnum = pgEnum("depth_unit", DepthUnit);

export const SizeUnit: [string, ...string[]] = ["kWp", "kW", "watt", "storey"];
export const sizeUnitEnum = pgEnum("size_unit", SizeUnit);

export const CostUnit: [string, ...string[]] = [
  "gbp_sq_meter",
  "gbp_per_unit",
  "gbp_per_m2",
  "gbp_per_m",
];
export const costUnitEnum = pgEnum("cost_unit", CostUnit);

export const RValueUnit: [string, ...string[]] = [
  "square_meter_kelvin_per_watt",
];
export const rValueUnitEnum = pgEnum("r_value_unit", RValueUnit);

export const ThermalConductivityUnit: [string, ...string[]] = [
  "watt_per_meter_kelvin",
];
export const thermalConductivityUnitEnum = pgEnum(
  "thermal_conductivity_unit",
  ThermalConductivityUnit
);

export const material = pgTable("material", {
  id: bigserial("id", { mode: "bigint" }).primaryKey(),
  type: materialTypeEnum("type").notNull(),
  description: text("description").notNull(),
  depth: json("depth").$type<number[]>(),
  depth_unit: depthUnitEnum("depth_unit"),

  costUnit: costUnitEnum("cost_unit"),
  rValuePerMm: real("r_value_per_mm"),
  rValueUnit: rValueUnitEnum("r_value_unit"),
  thermalConductivity: real("thermal_conductivity"),
  thermalConductivityUnit: thermalConductivityUnitEnum(
    "thermal_conductivity_unit"
  ),
  link: text("link"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  isActive: boolean("is_active").notNull().default(true),
  prime_material_cost: real("prime_material_cost"),
  material_cost: real("material_cost"),
  labour_cost: real("labour_cost"),
  labour_hours_per_unit: real("labour_hours_per_unit"),
  plant_cost: real("plant_cost"),
  total_cost: real("total_cost"),
  cost: json("cost").$type<number[]>(),
  notes: text("notes"),
  isInstallerQuote: boolean("is_installer_quote").default(false),
  innovationRate: real("innovation_rate").default(0),
  size: real("size"),
  // Can be null
  sizeUnit: sizeUnitEnum("size_unit"),
  includesScaffolding: boolean("includes_scaffolding").default(false),
  includesBattery: boolean("includes_battery").default(false),
  batterySize: real("battery_size"),
});

export type Material = InferModel<typeof material, "select">;
