import { eq } from 'drizzle-orm'
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { locations } from '../db/schema/stores.js'
import { AppError } from '../lib/errors.js'

export type TaxCategory = 'goods' | 'service' | 'exempt'

export const TaxService = {
  /**
   * Get the tax rate for a location, resolved by tax category:
   * - "goods"   → location.taxRate (default)
   * - "service" → location.serviceTaxRate, falls back to taxRate
   * - "exempt"  → 0
   *
   * Returns 0 with no warning for exempt items.
   * Returns 0 with warning if no rate is configured on the location.
   */
  async getRateForLocation(
    db: PostgresJsDatabase<any>,
    locationId: string,
    taxCategory: TaxCategory = 'goods',
  ): Promise<number> {
    if (taxCategory === 'exempt') return 0

    const [location] = await db
      .select({ taxRate: locations.taxRate, serviceTaxRate: locations.serviceTaxRate })
      .from(locations)
      .where(eq(locations.id, locationId))
      .limit(1)

    if (!location) return 0

    if (taxCategory === 'service') {
      // Use service rate if set, otherwise fall back to goods rate
      const rate = location.serviceTaxRate ?? location.taxRate
      return rate ? parseFloat(rate) : 0
    }

    // Default: goods rate
    return location.taxRate ? parseFloat(location.taxRate) : 0
  },

  calculateTax(amount: number, rate: number): number {
    return Math.round(amount * rate * 100) / 100
  },

  /**
   * Swedish rounding: round to nearest $0.05 for cash payments.
   * Only affects the final total — tax and line items stay exact.
   */
  roundToNickel(amount: number): number {
    return Math.round(amount * 20) / 20
  },

  /**
   * Map repair line item types to tax categories:
   * - "part"      → goods (taxable)
   * - "labor"     → service (may be taxed differently)
   * - "flat_rate" → goods (conservative — includes parts)
   * - "misc"      → goods (default)
   */
  repairItemTypeToTaxCategory(itemType: string): TaxCategory {
    switch (itemType) {
      case 'labor':
        return 'service'
      case 'consumable':
        return 'exempt'
      case 'part':
      case 'flat_rate':
      case 'misc':
      default:
        return 'goods'
    }
  },

  // TODO: Integrate with a real tax rate API (TaxJar, Avalara, etc.)
  // Set TAX_API_KEY env var when ready.
  async lookupByZip(
    _zip: string,
  ): Promise<{ zip: string; rate: number; state_rate: number; county_rate: number; city_rate: number }> {
    if (!process.env.TAX_API_KEY) {
      throw new AppError('Tax rate lookup is not configured. Set TAX_API_KEY to enable automatic lookup.', 501)
    }

    // Placeholder — replace with real API call
    throw new AppError('Tax rate lookup not yet implemented', 501)
  },
}
