import { type ActionReturnType, actions } from 'astro:actions';
import { writable } from 'svelte/store';
import { actionErrorPopup } from '@util/action.ts';

// types
export type Reports = Exclude<ActionReturnType<typeof actions.report.reports>['data'], undefined>['reports'];
export type Report = Reports[0];

export type ReportStatus = Exclude<
  Exclude<ActionReturnType<typeof actions.report.reportStatus>['data'], undefined>['reportStatus'],
  null
> & { strikeReasonId: number | null };

export type StrikeReasons = Exclude<
  ActionReturnType<typeof actions.report.strikeReasons>['data'],
  undefined
>['strikeReasons'];

// state
export const reports = writable<Reports>([]);

// actions
export async function fetchReports(
  reporterUsername: string | null,
  reportedUsername: string | null,
  includeDrafts: boolean
) {
  const { data, error } = await actions.report.reports({
    reporter: reporterUsername,
    reported: reportedUsername,
    includeDrafts: includeDrafts
  });
  if (error) {
    actionErrorPopup(error);
    return;
  }

  reports.set(data.reports);
}

export async function addReport(report: Report) {
  const { data, error } = await actions.report.addReport({
    reason: report.reason,
    body: report.body,
    createdAt: report.createdAt as unknown as string,
    reporter: report.reporter.id,
    reported: report.reported?.id ?? null
  });
  if (error) {
    actionErrorPopup(error);
    return;
  }

  reports.update((old) => {
    old.push(Object.assign(report, { id: data.id, status: null }));
    return old;
  });
}

export async function getReportStatus(report: Report) {
  const { data, error } = await actions.report.reportStatus({ reportId: report.id });
  if (error) {
    actionErrorPopup(error);
    return;
  }

  return data.reportStatus;
}

export async function editReport(report: Report) {
  const { error } = await actions.report.editReport({
    reportId: report.id,
    reported: report.reported?.id ?? null
  });

  if (error) {
    actionErrorPopup(error);
  }
}

export async function editReportStatus(report: Report, reportStatus: ReportStatus) {
  const { error } = await actions.report.editReportStatus({
    reportId: report.id,
    status: reportStatus.status,
    notice: reportStatus.notice,
    statement: reportStatus.statement,
    strikeReasonId: reportStatus.strikeReasonId
  });

  if (error) {
    actionErrorPopup(error);
  }
}

export async function getReportAttachments(report: Report) {
  const { data, error } = await actions.report.reportAttachments({
    reportId: report.id
  });
  if (error) {
    actionErrorPopup(error);
    return;
  }

  return data.reportAttachments;
}

export async function getStrikeReasons() {
  const { data, error } = await actions.report.strikeReasons();
  if (error) {
    actionErrorPopup(error);
    return;
  }

  return data.strikeReasons;
}
