export interface MatchResult {
  scoreHome: number;
  scoreAway: number;
  htScoreHome: number | null;
  htScoreAway: number | null;
}

export interface PickRef {
  market: string;
  pick: string;
  stake_units: number;
  odds: number | null;
}

type Resolver = (pick: string, r: MatchResult) => boolean | null;

const ms1x2: Resolver = (pick, r) => {
  const outcome =
    r.scoreHome > r.scoreAway ? "1" : r.scoreHome < r.scoreAway ? "2" : "X";
  return pick === outcome;
};

const ht1x2: Resolver = (pick, r) => {
  if (r.htScoreHome === null || r.htScoreAway === null) return null;
  const outcome =
    r.htScoreHome > r.htScoreAway
      ? "1"
      : r.htScoreHome < r.htScoreAway
        ? "2"
        : "X";
  return pick === outcome;
};

const overUnder =
  (line: number): Resolver =>
  (pick, r) => {
    const total = r.scoreHome + r.scoreAway;
    if (total === line) return null;
    const isOver = total > line;
    if (pick === "Üst" || pick === "Ust" || pick.toLowerCase() === "over")
      return isOver;
    if (pick === "Alt" || pick.toLowerCase() === "under") return !isOver;
    return null;
  };

const overUnderHt =
  (line: number): Resolver =>
  (pick, r) => {
    if (r.htScoreHome === null || r.htScoreAway === null) return null;
    const total = r.htScoreHome + r.htScoreAway;
    if (total === line) return null;
    const isOver = total > line;
    if (pick === "Üst" || pick === "Ust" || pick.toLowerCase() === "over")
      return isOver;
    if (pick === "Alt" || pick.toLowerCase() === "under") return !isOver;
    return null;
  };

const btts: Resolver = (pick, r) => {
  const both = r.scoreHome > 0 && r.scoreAway > 0;
  if (pick === "Var" || pick === "KG Var" || pick.toLowerCase() === "yes")
    return both;
  if (pick === "Yok" || pick === "KG Yok" || pick.toLowerCase() === "no")
    return !both;
  return null;
};

const htft: Resolver = (pick, r) => {
  if (r.htScoreHome === null || r.htScoreAway === null) return null;
  const ht =
    r.htScoreHome > r.htScoreAway
      ? "1"
      : r.htScoreHome < r.htScoreAway
        ? "2"
        : "X";
  const ft =
    r.scoreHome > r.scoreAway ? "1" : r.scoreHome < r.scoreAway ? "2" : "X";
  const normalized = pick.replace(/\s/g, "").toUpperCase();
  return normalized === `${ht}/${ft}`;
};

const doubleChance: Resolver = (pick, r) => {
  const ft =
    r.scoreHome > r.scoreAway ? "1" : r.scoreHome < r.scoreAway ? "2" : "X";
  const raw = pick.replace(/\s/g, "").toUpperCase();
  // Accept "1/X", "1-X" (split form) AND ayraçsız "1X", "X2", "12" (model emits ayraçsız).
  let pair: string[] = raw.split(/\/|-/);
  if (pair.length === 1) {
    if (raw === "1X" || raw === "X2" || raw === "12") {
      pair = raw.split("");
    } else if (raw === "X1" || raw === "2X" || raw === "21") {
      pair = raw.split("");
    } else {
      return null;
    }
  }
  if (pair.length !== 2) return null;
  return pair.includes(ft);
};

const oddEven: Resolver = (pick, r) => {
  const total = r.scoreHome + r.scoreAway;
  const isOdd = total % 2 === 1;
  if (pick === "Tek" || pick.toLowerCase() === "odd") return isOdd;
  if (pick === "Çift" || pick === "Cift" || pick.toLowerCase() === "even")
    return !isOdd;
  return null;
};

const resolvers: Record<string, Resolver> = {
  MS: ms1x2,
  ML: ms1x2,
  "1X2": ms1x2,
  HT: ht1x2,
  IY: ht1x2,
  OU05: overUnder(0.5),
  OU15: overUnder(1.5),
  OU25: overUnder(2.5),
  OU35: overUnder(3.5),
  OU45: overUnder(4.5),
  TOTAL: overUnder(2.5),
  OU05_HT: overUnderHt(0.5),
  OU15_HT: overUnderHt(1.5),
  OU25_HT: overUnderHt(2.5),
  HT_OU05: overUnderHt(0.5),
  HT_OU15: overUnderHt(1.5),
  HT_OU25: overUnderHt(2.5),
  BTTS: btts,
  KG: btts,
  HTFT: htft,
  IYMS: htft,
  DC: doubleChance,
  CIFTE_SANS: doubleChance,
  OE: oddEven,
  TEKCIFT: oddEven,
};

export function resolveOutcomeForPick(
  pick: PickRef,
  result: MatchResult,
): boolean | null {
  const market = pick.market.toUpperCase().replace(/[\s-]/g, "_");
  const resolver = resolvers[market] ?? resolvers[pick.market];
  if (!resolver) return null;
  try {
    return resolver(pick.pick, result);
  } catch {
    return null;
  }
}

export function computeUnitProfit(
  won: boolean,
  stakeUnits: number,
  odds: number | null,
): number {
  const stake = Number.isFinite(stakeUnits) && stakeUnits > 0 ? stakeUnits : 1;
  if (!won) return -stake;
  if (!odds || odds <= 1) return 0;
  return Number((stake * (odds - 1)).toFixed(4));
}
