import type { Product } from "@/lib/data/products"; export type StorageNote = { icon: "thermometer-outline" | "sunny-outline" | "happy-outline" | "water-outline"; title: string; body: string; }; export type DrugFacts = { /** Short therapeutic label shown above the product name. */ useCase: string; /** Dose form: Tablet, Syrup, Cream, Device… */ form: string; genericName: string; brandNames: string; drugClass: string; /** Selectable strengths on the detail page. Empty for non-dosed products. */ dosages: string[]; sideEffects: { mild: string[]; severe: string[] }; storage: StorageNote[]; directions: { title: string; body: string }[]; stockCount: number; /** Pharmacist guidance shown in the safety callout. */ advice: string; }; const CATEGORY_USE_CASE: Record = { medicines: "General Medicine", vitamins: "Supplements", "personal-care": "Personal Care", diabetic: "Diabetes Care", devices: "Medical Device", baby: "Baby Care", "first-aid": "First Aid", wellness: "Sexual Wellness", }; const CATEGORY_FORM: Record = { medicines: "Tablet", vitamins: "Tablet", "personal-care": "Topical", diabetic: "Tablet", devices: "Device", baby: "Topical", "first-aid": "Supply", wellness: "Tablet", }; /** Per-product clinical overrides. Everything else falls back to category defaults. */ const OVERRIDES: Record> = { "panadol-advance": { useCase: "Pain & Fever", genericName: "Paracetamol (Acetaminophen)", brandNames: "Panadol, Tylenol, Calpol", drugClass: "Analgesic / Antipyretic", dosages: ["500mg", "650mg"], sideEffects: { mild: ["Nausea", "Sleepiness", "Stomach upset"], severe: ["Liver damage", "Rash", "Breathing issues"], }, advice: "Do not exceed 4g of paracetamol in 24 hours across all products.", }, paracetamol: { useCase: "Pain & Fever", genericName: "Paracetamol", brandNames: "Panadol, Tylenol", drugClass: "Analgesic / Antipyretic", dosages: ["500mg"], advice: "Avoid alcohol while taking this medicine.", }, "paracetamol-tylenol": { useCase: "Pain & Fever", genericName: "Acetaminophen", brandNames: "Tylenol, Panadol", drugClass: "Analgesic", dosages: ["500mg", "650mg"], }, "paracetamol-caffeine": { useCase: "Headache Relief", genericName: "Paracetamol + Caffeine", brandNames: "Panadol Extra", drugClass: "Analgesic combination", dosages: ["500mg / 65mg"], advice: "Contains caffeine — limit other caffeinated drinks.", }, snip: { useCase: "Cold & Flu", genericName: "Paracetamol + Pseudoephedrine + Chlorphenamine", brandNames: "SNIP", drugClass: "Decongestant combination", sideEffects: { mild: ["Drowsiness", "Dry mouth", "Dizziness"], severe: ["Rapid heartbeat", "High blood pressure"], }, advice: "May cause drowsiness. Do not drive until you know how it affects you.", }, metformin: { useCase: "Diabetes Care", genericName: "Metformin hydrochloride", brandNames: "Glucophage, Glumet", drugClass: "Biguanide antidiabetic", dosages: ["500mg", "850mg", "1000mg"], sideEffects: { mild: ["Nausea", "Diarrhoea", "Metallic taste"], severe: ["Lactic acidosis", "Vitamin B12 deficiency"], }, advice: "Take with meals to reduce stomach upset. Requires a valid prescription.", }, ciprofloxacin: { useCase: "Antibiotic", genericName: "Ciprofloxacin", brandNames: "Cipro, Ciprobay", drugClass: "Fluoroquinolone antibiotic", dosages: ["250mg", "500mg"], sideEffects: { mild: ["Nausea", "Headache", "Dizziness"], severe: ["Tendon rupture", "Nerve damage"], }, advice: "Finish the full course even if you feel better.", }, azitro: { useCase: "Antibiotic", genericName: "Azithromycin", brandNames: "Zithromax, Azitro", drugClass: "Macrolide antibiotic", dosages: ["250mg", "500mg"], advice: "Usually taken once daily for 3 days. Complete the course as prescribed.", }, diclofenac: { useCase: "Pain & Inflammation", genericName: "Diclofenac sodium", brandNames: "Voltaren, Cataflam", drugClass: "NSAID", dosages: ["25mg", "50mg", "75mg"], sideEffects: { mild: ["Indigestion", "Headache", "Dizziness"], severe: ["Stomach bleeding", "Kidney issues"], }, advice: "Take after food. Avoid if you have a history of stomach ulcers.", }, pantoprazole: { useCase: "Acid Reflux", genericName: "Pantoprazole sodium", brandNames: "Protonix, Pantocid", drugClass: "Proton pump inhibitor", dosages: ["20mg", "40mg"], advice: "Take 30–60 minutes before your first meal of the day.", }, desloratidine: { useCase: "Allergy Relief", genericName: "Desloratadine", brandNames: "Clarinex, Aerius", drugClass: "Antihistamine", dosages: ["5mg"], advice: "Non-drowsy for most people, but avoid driving until you're sure.", }, "nat-c-vitamin-c": { useCase: "Immune Support", genericName: "Ascorbic acid", brandNames: "Nat C, Redoxon", drugClass: "Vitamin supplement", dosages: ["500mg", "1000mg"], sideEffects: { mild: ["Stomach upset", "Heartburn"], severe: ["Kidney stones (high doses)"] }, }, gofen: { useCase: "Pain & Inflammation", genericName: "Ibuprofen", brandNames: "Brufen, Advil, Gofen", drugClass: "NSAID", dosages: ["200mg", "400mg"], advice: "Take with food or milk to protect your stomach.", }, quemox: { useCase: "Antibiotic", genericName: "Amoxicillin", brandNames: "Amoxil, Quemox", drugClass: "Penicillin antibiotic", dosages: ["250mg", "500mg"], advice: "Tell your pharmacist about any penicillin allergy before use.", }, sildenafil: { useCase: "Sexual Wellness", genericName: "Sildenafil citrate", brandNames: "Viagra, Cialis (tadalafil alt.)", drugClass: "PDE5 inhibitor", dosages: ["25mg", "50mg", "100mg"], advice: "Never combine with nitrate heart medicines. Prescription required.", }, "ors-sachets": { useCase: "Rehydration", genericName: "Oral rehydration salts", brandNames: "ORS, Hydralyte", drugClass: "Electrolyte replacement", advice: "Dissolve one sachet in 200ml of clean water. Use within 24 hours.", }, "cough-syrup": { useCase: "Cough Relief", form: "Syrup", genericName: "Dextromethorphan / Guaifenesin", brandNames: "Robitussin, Benylin", drugClass: "Antitussive / Expectorant", dosages: ["100ml", "200ml"], }, "lubricating-eye-drops": { useCase: "Eye Care", form: "Drops", }, "eye-drops-lubricating": { useCase: "Eye Care", form: "Drops", genericName: "Carboxymethylcellulose", brandNames: "Refresh Tears, Optive", drugClass: "Ocular lubricant", }, "blood-pressure-monitor": { useCase: "Monitoring", form: "Device", genericName: "Upper-arm oscillometric monitor", brandNames: "HealthTech", drugClass: "Class II medical device", }, "glucose-meter-kit": { useCase: "Diabetes Care", form: "Device", genericName: "Blood glucose monitoring system", brandNames: "DiaCare", drugClass: "Class II medical device", }, }; const DEFAULT_SIDE_EFFECTS: DrugFacts["sideEffects"] = { mild: ["Nausea", "Headache", "Mild dizziness"], severe: ["Allergic reaction", "Difficulty breathing"], }; const DEFAULT_STORAGE: StorageNote[] = [ { icon: "thermometer-outline", title: "Temperature", body: "Store at room temperature, between 20°C and 25°C.", }, { icon: "sunny-outline", title: "Light & moisture", body: "Keep in a dry place, away from direct sunlight.", }, { icon: "happy-outline", title: "Children", body: "Keep out of reach of children to prevent accidental ingestion.", }, ]; const DEFAULT_DIRECTIONS: DrugFacts["directions"] = [ { title: "Check with your pharmacist", body: "Confirm the dose is right for your age, weight and other medicines.", }, { title: "Take as directed", body: "Follow the schedule on the label. Do not double up on a missed dose.", }, { title: "Take with water", body: "Swallow whole with a full glass of water unless told otherwise.", }, { title: "Track your response", body: "Stop and contact us if symptoms persist beyond 3 days.", }, ]; const DEVICE_DIRECTIONS: DrugFacts["directions"] = [ { title: "Unbox and inspect", body: "Check all parts are present and undamaged." }, { title: "Prepare", body: "Sit still for 5 minutes and rest your arm at heart level." }, { title: "Measure", body: "Follow the on-screen prompts and stay quiet during the reading." }, { title: "Log the result", body: "Record readings so your pharmacist can review trends." }, ]; /** Deterministic pseudo-stock so the number is stable between renders. */ function stockFor(product: Product): number { if (!product.inStock) return 0; const seed = product.id .split("") .reduce((total, char) => total + char.charCodeAt(0), 0); return 8 + (seed % 44); } export function getDrugFacts(product: Product): DrugFacts { const override = OVERRIDES[product.slug] ?? {}; const isDevice = product.category === "devices" || product.category === "first-aid"; return { useCase: override.useCase ?? CATEGORY_USE_CASE[product.category] ?? "Healthcare", form: override.form ?? CATEGORY_FORM[product.category] ?? "Unit", genericName: override.genericName ?? product.name, brandNames: override.brandNames ?? product.brand, drugClass: override.drugClass ?? CATEGORY_USE_CASE[product.category] ?? "Healthcare product", dosages: override.dosages ?? [], sideEffects: override.sideEffects ?? (isDevice ? { mild: ["Skin irritation"], severe: [] } : DEFAULT_SIDE_EFFECTS), storage: override.storage ?? DEFAULT_STORAGE, directions: override.directions ?? (isDevice ? DEVICE_DIRECTIONS : DEFAULT_DIRECTIONS), stockCount: override.stockCount ?? stockFor(product), advice: override.advice ?? (product.requiresPrescription ? "A valid prescription is required. Our pharmacist will verify it before dispatch." : "Speak to our pharmacist if you are pregnant, breastfeeding or taking other medicines."), }; } /** Star distribution for the review summary, weighted by the product rating. */ export function getReviewBreakdown(product: Product) { const weights = [0.62, 0.22, 0.09, 0.04, 0.03]; const shift = Math.max(0, Math.round((4.8 - product.rating) * 10)) / 100; return [5, 4, 3, 2, 1].map((stars, index) => { const weight = Math.max(0.01, weights[index] - (index === 0 ? shift : -shift / 4)); return { stars, count: Math.max(1, Math.round(product.reviews * weight)) }; }); }