import type { CategoryType, FinancialPhase, MoneyRecordType } from "@prisma/client";

export const financialPhaseLabels: Record<FinancialPhase, string> = {
  PRE_PURCHASE: "Pre-Purchase",
  ACQUISITION_CLOSING: "Acquisition / Closing",
  RENOVATION_CAPITAL_IMPROVEMENT: "Renovation / Capital Improvement",
  RENTAL_OPERATION: "Rental Operation",
  POST_RENTAL_REPAIR_MAINTENANCE: "Post-Rental Repair / Maintenance",
  OTHER: "Other"
};

export const recordTypeLabels: Record<MoneyRecordType, string> = {
  EXPENSE: "Expense",
  PARTNER_CONTRIBUTION: "Partner Contribution",
  RENTAL_INCOME: "Rental Income",
  SECURITY_DEPOSIT_HELD: "Security Deposit Held",
  SECURITY_DEPOSIT_RETURNED: "Security Deposit Returned",
  OWNER_DISTRIBUTION: "Owner Distribution",
  PARTNER_REIMBURSEMENT: "Partner Reimbursement",
  OTHER_INCOME: "Other Income"
};

export const purchaseCostPhases: FinancialPhase[] = ["PRE_PURCHASE", "ACQUISITION_CLOSING"];
export const renovationCostPhases: FinancialPhase[] = ["RENOVATION_CAPITAL_IMPROVEMENT"];
export const operatingCostPhases: FinancialPhase[] = ["RENTAL_OPERATION", "POST_RENTAL_REPAIR_MAINTENANCE"];

const prePurchaseKeywords = ["inspection", "appraisal", "travel", "application", "due diligence", "consultation"];
const acquisitionKeywords = ["down payment", "closing", "attorney", "title", "lender", "recording", "insurance"];
const renovationKeywords = [
  "renovation",
  "home depot",
  "lowe",
  "labor",
  "permit",
  "tool",
  "floor",
  "kitchen",
  "bathroom",
  "electrical",
  "plumbing",
  "paint",
  "construction"
];
const operatingKeywords = ["mortgage", "property tax", "utility", "water", "gas", "electric", "internet", "cleaning"];
const repairKeywords = ["repair", "maintenance"];

function includesAny(value: string, keywords: string[]) {
  return keywords.some((keyword) => value.includes(keyword));
}

export function inferFinancialPhase(input: {
  categoryType?: CategoryType | null;
  categoryName?: string | null;
  description?: string | null;
  vendor?: string | null;
  sourceSheet?: string | null;
}): FinancialPhase {
  const haystack = [input.categoryName, input.description, input.vendor, input.sourceSheet]
    .filter(Boolean)
    .join(" ")
    .toLowerCase();

  if (includesAny(haystack, prePurchaseKeywords)) return "PRE_PURCHASE";
  if (includesAny(haystack, acquisitionKeywords)) return "ACQUISITION_CLOSING";
  if (includesAny(haystack, renovationKeywords)) return "RENOVATION_CAPITAL_IMPROVEMENT";
  if (includesAny(haystack, repairKeywords)) return "POST_RENTAL_REPAIR_MAINTENANCE";
  if (includesAny(haystack, operatingKeywords)) return "RENTAL_OPERATION";

  if (input.categoryType === "PURCHASE_COST") return "ACQUISITION_CLOSING";
  if (input.categoryType === "RENOVATION_EXPENSE") return "RENOVATION_CAPITAL_IMPROVEMENT";
  if (input.categoryType === "OPERATING_EXPENSE") return "RENTAL_OPERATION";
  return "OTHER";
}

export function phaseFromForm(value: FormDataEntryValue | null, fallback: FinancialPhase = "OTHER"): FinancialPhase {
  const phase = String(value ?? "");
  return Object.keys(financialPhaseLabels).includes(phase) ? (phase as FinancialPhase) : fallback;
}

export function recordTypeFromForm(value: FormDataEntryValue | null, fallback: MoneyRecordType = "EXPENSE"): MoneyRecordType {
  const recordType = String(value ?? "");
  return Object.keys(recordTypeLabels).includes(recordType) ? (recordType as MoneyRecordType) : fallback;
}

export function phaseMatches(phase: FinancialPhase | null | undefined, allowedPhases: FinancialPhase[]) {
  return allowedPhases.length === 0 || allowedPhases.includes(phase ?? "OTHER");
}
