import { MockupMatchProvider } from '../provider/MockupMatchProvider'
import { MockupPropertyProvider } from '../provider/MockupPropertyProvider'
import { MockupNeedProvider } from '../provider/MockupNeedProvider'
import type { MatchFilters } from '../provider/IMatchProvider'
import type { Match } from '../domain/match'
import type { Need } from '../domain/need'
import type { Property } from '../domain/property'
import type { StrongMatchItem } from '../domain/dashboard'
import type { ScoreBreakdown } from '../domain/match'
import type { ListResponse, ItemResponse } from './types'
import { buildFullMatch, computeRankedMatches } from '../features/matching/rankingEngine'

const provider = MockupMatchProvider

export const matchService = {
  async getAll(filters?: MatchFilters): Promise<ListResponse<Match>> {
    const data = await provider.getAll(filters)
    return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
  },
  async getById(id: string): Promise<ItemResponse<Match | null>> {
    const data = await provider.getById(id)
    return { data }
  },
  async getByNeed(needId: string): Promise<ListResponse<Match>> {
    const data = await provider.getByNeed(needId)
    return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
  },
  async getByProperty(propertyId: string): Promise<ListResponse<Match>> {
    const data = await provider.getByProperty(propertyId)
    return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
  },
  async approve(id: string, reviewedBy: string): Promise<ItemResponse<Match>> {
    const data = await provider.approve(id, reviewedBy)
    return { data }
  },

  async getMatchesForProperty(propertyId: string): Promise<ListResponse<Match>> {
    const data = await provider.getByProperty(propertyId)
    return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
  },

  async getMatchDetail(id: string): Promise<ItemResponse<Match | null>> {
    const data = await provider.getById(id)
    return { data }
  },

  async getScoreBreakdown(matchId: string): Promise<ItemResponse<ScoreBreakdown | null>> {
    const match = await provider.getById(matchId)
    return { data: match?.scoreBreakdown ?? null }
  },

  // ── Engine-based methods ──────────────────────────────────────────────────

  computeMatch(need: Need, property: Property): Match {
    return buildFullMatch(need, property)
  },

  async computeMatchesForNeed(needId: string): Promise<ListResponse<Match>> {
    const [need, properties] = await Promise.all([
      MockupNeedProvider.getById(needId),
      MockupPropertyProvider.getAll(),
    ])
    if (!need) return { data: [], meta: { total: 0, page: 1, pageSize: 0, hasMore: false } }
    const data = computeRankedMatches(need, properties)
    return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
  },

  async getStrongMatches(minScore = 80): Promise<StrongMatchItem[]> {
    const [matches, properties] = await Promise.all([
      provider.getAll(),
      MockupPropertyProvider.getAll(),
    ])
    return matches
      .filter(m => m.matchScore >= minScore)
      .slice(0, 5)
      .map(m => {
        const prop = properties.find(p => p.id === m.propertyId)
        const topFactor = m.positiveFactors?.[0]
        const firstAction = m.nextBestActions?.[0]
        return {
          matchId: m.id,
          propertyId: m.propertyId,
          propertyTitle: prop?.title ?? 'Unbekanntes Objekt',
          propertyAddress: prop?.address
            ? `${prop.address.street} ${prop.address.houseNumber}, ${prop.address.city}`
            : '–',
          needSummary: m.needId,
          matchScore: m.matchScore,
          topReason: topFactor?.explanation ?? topFactor?.criterion ?? '–',
          missingDataCount: m.missingData?.length ?? 0,
          nextBestAction: firstAction?.label ?? '–',
        } satisfies StrongMatchItem
      })
  },
}
