import { initDb } from "@/lib/db";
import { loadFeedWindow } from "@/lib/domestic/feed-engine";
import { formatDomesticAnswer } from "@/lib/domestic/rules";
import {
  CONSENT_KEYS,
  getActiveConsentRecordId,
  getCurrentPolicies,
  getLatestConsentRecord,
} from "@/lib/participant/consent";
import type { DomesticQuestionVersion } from "@/lib/db/models/domestic-question-version";
import type { DomesticQuestion } from "@/lib/db/models/domestic-question";
import type {
  DomesticOptionsConfig,
  DomesticQuestionType,
  QueueReason,
} from "@/types/participant";

export interface FeedItemView {
  queueItemId: string;
  code: string;
  categoryName: string | null;
  reason: QueueReason;
  type: DomesticQuestionType;
  prompt: string;
  helpText: string | null;
  optionsConfig: DomesticOptionsConfig | null;
}

export interface DomesticFeedView {
  consentGranted: boolean;
  completedCount: number;
  skippedCount: number;
  items: FeedItemView[];
}

type FeedRow = {
  id: string;
  reason: QueueReason;
  version?: DomesticQuestionVersion;
  question?: DomesticQuestion & { category?: { name: string } };
};

export async function getDomesticFeed(
  participantProfileId: string
): Promise<DomesticFeedView> {
  const { sequelize } = initDb();

  const consentGranted = Boolean(
    await getActiveConsentRecordId(participantProfileId, CONSENT_KEYS.domesticFeed)
  );

  if (!consentGranted) {
    const { ParticipantDomesticState } = initDb();
    const state = await ParticipantDomesticState.findOne({
      where: { participantProfileId },
    });
    return {
      consentGranted,
      completedCount: state?.completedCount ?? 0,
      skippedCount: state?.skippedCount ?? 0,
      items: [],
    };
  }

  return sequelize.transaction(async (t) => {
    const { state, items } = await loadFeedWindow(participantProfileId, t);
    return {
      consentGranted,
      completedCount: state.completedCount,
      skippedCount: state.skippedCount,
      items: (items as unknown as FeedRow[])
        .filter((i) => i.version && i.question)
        .map((i) => ({
          queueItemId: i.id,
          code: i.question!.code,
          categoryName: i.question!.category?.name ?? null,
          reason: i.reason,
          type: i.version!.type,
          prompt: i.version!.prompt,
          helpText: i.version!.helpText ?? null,
          optionsConfig: i.version!.optionsConfig ?? null,
        })),
    };
  });
}

export interface ActivityEntry {
  id: string;
  code: string;
  prompt: string;
  answer: string;
  versionNumber: number;
  answeredAt: string;
}

export async function getParticipantActivity(
  participantProfileId: string,
  limit = 100
): Promise<ActivityEntry[]> {
  const { DomesticAnswer, DomesticQuestion, DomesticQuestionVersion } = initDb();
  const rows = await DomesticAnswer.findAll({
    where: { participantProfileId },
    include: [
      { model: DomesticQuestion, as: "question", attributes: ["code"] },
      { model: DomesticQuestionVersion, as: "version" },
    ],
    order: [["answeredAt", "DESC"]],
    limit,
  });

  return rows.map((r) => {
    const row = r as typeof r & {
      question?: { code: string };
      version?: DomesticQuestionVersion;
    };
    return {
      id: r.id,
      code: row.question?.code ?? "—",
      prompt: row.version?.prompt ?? "",
      answer: row.version
        ? formatDomesticAnswer(row.version.type, row.version.optionsConfig, r.value)
        : String(r.value ?? "—"),
      versionNumber: row.version?.versionNumber ?? 1,
      answeredAt: r.answeredAt.toISOString(),
    };
  });
}

export interface ConsentView {
  key: string;
  title: string;
  purpose: string;
  policyText: string;
  version: number;
  isRequired: boolean;
  retentionDays: number | null;
  granted: boolean;
  decidedAt: string | null;
}

export async function getParticipantConsents(
  participantProfileId: string
): Promise<ConsentView[]> {
  const policies = await getCurrentPolicies([
    CONSENT_KEYS.participantTerms,
    CONSENT_KEYS.domesticFeed,
  ]);
  return Promise.all(
    policies.map(async (p) => {
      const latest = await getLatestConsentRecord(participantProfileId, p.id);
      return {
        key: p.key,
        title: p.title,
        purpose: p.purpose,
        policyText: p.policyText,
        version: p.version,
        isRequired: p.isRequired,
        retentionDays: p.retentionDays ?? null,
        granted: latest?.status === "granted",
        decidedAt: latest ? latest.createdAt.toISOString() : null,
      };
    })
  );
}

export async function getParticipantSummary(participantProfileId: string) {
  const { ParticipantDomesticState, DomesticAnswer } = initDb();
  const [state, answers] = await Promise.all([
    ParticipantDomesticState.findOne({ where: { participantProfileId } }),
    DomesticAnswer.count({ where: { participantProfileId } }),
  ]);
  const consentGranted = Boolean(
    await getActiveConsentRecordId(participantProfileId, CONSENT_KEYS.domesticFeed)
  );
  return {
    answeredCount: answers,
    skippedCount: state?.skippedCount ?? 0,
    lastAnsweredAt: state?.lastAnsweredAt?.toISOString() ?? null,
    consentGranted,
  };
}
