import type { ClassValue } from 'clsx'
import { clsx } from 'clsx'
import { format } from 'date-fns'
import { twMerge } from 'tailwind-merge'
import { toast } from '~/components/pub/ui/toast'

export interface SelectOptionType<_T = string> {
  value: string
  label: string
  code?: string
}

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

export function mapToComboboxOptList(items: Record<string, string>): SelectOptionType<string>[] {
  if (!items) {
    return []
  }
  const result: SelectOptionType<string>[] = []
  Object.keys(items).forEach((item) => {
    result.push({
      label: items[item] as string,
      value: item,
      code: item,
    })
  })
  return result
}

/**
 * Mengkonversi string menjadi title case (huruf pertama setiap kata kapital)
 * @param str - String yang akan dikonversi
 * @returns String dalam format title case
 */
export function toTitleCase(str: string): string {
  return str.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase())
}


/**
 * Menghitung umur berdasarkan tanggal lahir
 * @param birthDate - Tanggal lahir dalam format Date atau string
 * @returns String umur dalam format "X tahun Y bulan" atau "X bulan" untuk bayi
 */
export function calculateAge(birthDate: Date | string | null | undefined): string {
  if (!birthDate) {
    return '-'
  }

  let birth: Date

  // Konversi ke Date object
  if (typeof birthDate === 'string') {
    birth = new Date(birthDate)
  } else {
    birth = birthDate
  }

  // Validasi tanggal
  if (isNaN(birth.getTime())) {
    return '-'
  }

  const today = new Date()
  const birthYear = birth.getFullYear()
  const birthMonth = birth.getMonth()
  const birthDay = birth.getDate()

  const currentYear = today.getFullYear()
  const currentMonth = today.getMonth()
  const currentDay = today.getDate()

  // Hitung tahun
  let years = currentYear - birthYear
  let months = currentMonth - birthMonth

  // Adjust jika bulan atau hari belum lewat
  if (months < 0 || (months === 0 && currentDay < birthDay)) {
    years--
    months += 12
  }

  if (currentDay < birthDay) {
    months--
  }

  // Pastikan months tidak negatif
  if (months < 0) {
    months += 12
  }

  // Format output
  if (years === 0) {
    if (months === 0) {
      // Hitung hari untuk bayi baru lahir
      const diffTime = today.getTime() - birth.getTime()
      const days = Math.floor(diffTime / (1000 * 60 * 60 * 24))
      return days <= 30 ? `${days} hari` : '1 bulan'
    }
    return `${months} bulan`
  } else if (months === 0) {
    return `${years} tahun`
  } else {
    return `${years} tahun ${months} bulan`
  }
}

export function formatDateToDatetimeLocal(inputDate: Date) { 
  const formattedString = format(inputDate, "yyyy-MM-dd'T'HH:mm")  
  return formattedString
}


/**
 * Converts a plain JavaScript object (including File objects) into a FormData instance.
 * @param {object} data - The object to convert (e.g., form values).
 * @returns {FormData} The new FormData object suitable for API submission.
 */
export function toFormData(data: Record<string, any>): FormData {
  const formData = new FormData();

  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      const value = data[key];

      // Handle File objects, Blobs, or standard JSON values
      if (value !== null && value !== undefined) {
        // Check if the value is a File/Blob instance
        if (value instanceof File || value instanceof Blob) {
          // Append the file directly
          formData.append(key, value);
        } else if (typeof value === 'object') {
          // Handle nested objects/arrays by stringifying them (optional, depends on API)
          // Note: Most APIs expect nested data to be handled separately or passed as JSON string
          // For simplicity, we stringify non-File objects.
          formData.append(key, JSON.stringify(value));
        } else {
          // Append standard string, number, or boolean values
          formData.append(key, value);
        }
      }
    }
  }

  return formData;
}

export function printFormData(formData: FormData) {
    console.log("--- FormData Contents ---");
    // Use the entries() iterator to loop through key/value pairs
    for (const [key, value] of formData.entries()) {
        if (value instanceof File) {
            console.log(`Key: ${key}, Value: [File: ${value.name}, Type: ${value.type}, Size: ${value.size} bytes]`);
        } else {
            console.log(`Key: ${key}, Value: "${value}"`);
        }
    }
    console.log("-------------------------");
}

export function unauthorizedToast() {
  toast({
    title: 'Unauthorized',
    description: 'You are not authorized to perform this action.',
    variant: 'destructive',
  })
}