import { VolumeData, WizardData, QuoteResult } from "./types";

// Volume conversion rates (to standard boxes)
export const CONVERSION_RATES = {
  fileBoxes: 1,
  filingCabinets: 8,
  bags: 0.5,
  pallets: 40
};

// Weight calculation (30 lbs per standard box)
export const WEIGHT_PER_BOX = 30;

// Bin definitions
export const BIN_WEIGHT = 200; // lbs per bin
export const BIN_BOXES = 10;   // boxes per bin
export const HALF_BIN_WEIGHT = 100; // lbs per half bin
export const HALF_BIN_BOXES = 5;    // boxes per half bin

// Pricing logic
export const PRICING = {
  mobile: { 
    firstBin: 140,      // First bin or 10 boxes or 200 lbs
    perBin: 85,         // Per additional bin or 200 lbs
    halfBin: 45         // Per half bin or 5 boxes or 100 lbs
  },
  offsite: { 
    flat: 55,           // 10 boxes or less
    base: 35,           // Base for more than 10 boxes
    perBox: 4           // Per additional box after 10
  },
  dropoff: { 
    base: 25,           // Base fee
    perBin: 35          // Per bin or 200 lbs
  }
};

export function calculateTotalBoxes(volumeData: VolumeData): number {
  return Object.keys(volumeData).reduce((total, type) => {
    const key = type as keyof VolumeData;
    const conversionRate = CONVERSION_RATES[key];
    return total + (volumeData[key] * conversionRate);
  }, 0);
}

export function calculateTotalWeight(totalBoxes: number): number {
  return totalBoxes * WEIGHT_PER_BOX;
}

export function calculateServiceQuote(serviceType: string, volumeData: VolumeData): string {
  const totalBoxes = calculateTotalBoxes(volumeData);
  const totalWeight = calculateTotalWeight(totalBoxes);

  switch (serviceType) {
    case "mobile":
      if (totalBoxes <= BIN_BOXES) {
        return `$${PRICING.mobile.firstBin}`;
      } else {
        const remainingBoxes = totalBoxes - BIN_BOXES;
        const fullBins = Math.floor(remainingBoxes / BIN_BOXES);
        const leftoverBoxes = remainingBoxes % BIN_BOXES;
        
        let price = PRICING.mobile.firstBin + (fullBins * PRICING.mobile.perBin);
        
        if (leftoverBoxes > 0 && leftoverBoxes <= HALF_BIN_BOXES) {
          price += PRICING.mobile.halfBin;
        } else if (leftoverBoxes > HALF_BIN_BOXES) {
          price += PRICING.mobile.perBin;
        }
        
        return `$${price}`;
      }
    
    case "offsite":
      if (totalBoxes <= 10) {
        return `$${PRICING.offsite.flat}`;
      } else {
        const price = PRICING.offsite.base + (totalBoxes - 10) * PRICING.offsite.perBox;
        return `$${price}`;
      }
    
    case "dropoff":
      const bins = Math.ceil(totalWeight / BIN_WEIGHT);
      return `$${PRICING.dropoff.base + (bins * PRICING.dropoff.perBin)}`;
    
    default:
      return "$0";
  }
}

export function calculateFinalQuote(data: WizardData): QuoteResult {
  const totalBoxes = calculateTotalBoxes(data.volumeData);
  const totalWeight = calculateTotalWeight(totalBoxes);
  
  let price = 0;
  let savings = 0;

  switch (data.serviceType) {
    case "mobile":
      if (totalBoxes <= BIN_BOXES) {
        price = PRICING.mobile.firstBin;
      } else {
        const remainingBoxes = totalBoxes - BIN_BOXES;
        const fullBins = Math.floor(remainingBoxes / BIN_BOXES);
        const leftoverBoxes = remainingBoxes % BIN_BOXES;
        
        price = PRICING.mobile.firstBin + (fullBins * PRICING.mobile.perBin);
        
        if (leftoverBoxes > 0 && leftoverBoxes <= HALF_BIN_BOXES) {
          price += PRICING.mobile.halfBin;
        } else if (leftoverBoxes > HALF_BIN_BOXES) {
          price += PRICING.mobile.perBin;
        }
      }
      savings = 30;
      break;
    
    case "offsite":
      if (totalBoxes <= 10) {
        price = PRICING.offsite.flat;
      } else {
        price = PRICING.offsite.base + (totalBoxes - 10) * PRICING.offsite.perBox;
      }
      savings = 25;
      break;
    
    case "dropoff":
      const bins = Math.ceil(totalWeight / BIN_WEIGHT);
      price = PRICING.dropoff.base + (bins * PRICING.dropoff.perBin);
      savings = 15;
      break;
  }

  return {
    totalBoxes,
    totalWeight,
    price,
    savings,
    serviceType: data.serviceType
  };
}

export function getServiceDisplayName(serviceType: string): string {
  switch (serviceType) {
    case "mobile":
      return "Mobile Shredding";
    case "offsite":
      return "Off-Site Shredding";
    case "dropoff":
      return "Drop-Off Service";
    default:
      return "Unknown Service";
  }
}

export function getTimelineDisplayName(timeline: string): string {
  switch (timeline) {
    case "asap":
      return "Within 24-48 hours";
    case "week":
      return "Within 7 days";
    case "flexible":
      return "Flexible scheduling";
    default:
      return "To be scheduled";
  }
}
