"use server";

import bcrypt from "bcryptjs";
import { redirect } from "next/navigation";
import {
  clearPatientSession,
  clearStaffSession,
  getPatientSession,
  requireStaff,
  setPatientSession,
  setStaffSession,
} from "@/lib/auth";
import { isLang } from "@/lib/catalog";
import { getStaffByUsername, updateStaffPassword } from "@/lib/db";
import {
  addTimelineEvent,
  createCaseRecord,
  getCase,
  getCaseByToken,
  issueCode,
  normalizeSentence,
  parseCaseForm,
  parseEventTime,
  sendStoredSms,
  setCaseLanguage,
  stageExists,
  updateCaseRecord,
  verifyPatientCode,
  type ActionResult,
} from "@/lib/cases";
import { text } from "@/lib/i18n";

export async function loginStaff(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  const username = String(form.get("username") ?? "").trim();
  const password = String(form.get("password") ?? "");
  const user = username ? getStaffByUsername(username) : undefined;
  if (!user || !bcrypt.compareSync(password, user.password_hash)) {
    return { ok: false, message: "نام کاربری یا گذرواژه درست نیست." };
  }
  await setStaffSession(user.id);
  redirect("/staff/cases");
}

export async function logoutStaff() {
  await clearStaffSession();
  redirect("/staff/login");
}

export async function changePassword(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  const user = await requireStaff();
  const current = String(form.get("current") ?? "");
  const next = String(form.get("next") ?? "");
  const again = String(form.get("again") ?? "");
  if (!bcrypt.compareSync(current, user.password_hash)) {
    return { ok: false, message: "گذرواژه فعلی درست نیست." };
  }
  if (next.length < 8) return { ok: false, message: "گذرواژه جدید حداقل ۸ نویسه باشد." };
  if (next !== again) return { ok: false, message: "تکرار گذرواژه یکسان نیست." };
  updateStaffPassword(user.id, bcrypt.hashSync(next, 10));
  return { ok: true, message: "گذرواژه عوض شد." };
}

export async function createCase(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  await requireStaff();
  const parsed = parseCaseForm(form);
  if (!parsed.ok) return parsed;
  const { id } = createCaseRecord(parsed.value);
  await sendStoredSms(id);
  redirect(`/staff/cases/${id}`);
}

export async function updateCase(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  await requireStaff();
  const id = Number(form.get("id"));
  if (!Number.isInteger(id) || !getCase(id)) return { ok: false, message: "پرونده پیدا نشد." };
  const parsed = parseCaseForm(form);
  if (!parsed.ok) return parsed;
  updateCaseRecord(id, parsed.value);
  redirect(`/staff/cases/${id}`);
}

export async function addStage(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  await requireStaff();
  const id = Number(form.get("id"));
  const record = Number.isInteger(id) ? getCase(id) : null;
  if (!record) return { ok: false, message: "پرونده پیدا نشد." };
  const stageId = String(form.get("stageId") ?? "");
  if (!stageExists(stageId)) return { ok: false, message: "مرحله را انتخاب کنید." };
  const happenedAt = parseEventTime(String(form.get("happenedAt") ?? ""));
  if (!happenedAt) return { ok: false, message: "زمان این لحظه درست نیست. وقت تهران را وارد کنید." };
  const sentence = normalizeSentence(stageId, record.language, String(form.get("sentence") ?? ""));
  addTimelineEvent(id, stageId, sentence, happenedAt);
  redirect(`/staff/cases/${id}`);
}

export async function reissueCode(form: FormData) {
  await requireStaff();
  const id = Number(form.get("id"));
  if (!Number.isInteger(id) || !getCase(id)) redirect("/staff/cases");
  issueCode(id, true);
  redirect(`/staff/cases/${id}`);
}

export async function patientLogin(_prev: ActionResult, form: FormData): Promise<ActionResult> {
  const token = String(form.get("token") ?? "");
  const record = getCaseByToken(token);
  const copy = text(record?.language ?? "fa");
  const mobile = String(form.get("mobile") ?? "").trim();
  const code = String(form.get("code") ?? "").trim();
  if (!record) return { ok: false, message: copy.invalid };
  if (!mobile || !code) return { ok: false, message: copy.required };
  const result = verifyPatientCode(token, mobile, code);
  if (!result.ok) {
    return { ok: false, message: result.reason === "locked" ? copy.locked : copy.invalid };
  }
  await setPatientSession(result.mobileKey);
  redirect(`/p/${token}/track`);
}

export async function setPatientLanguage(form: FormData) {
  const token = String(form.get("token") ?? "");
  const language = String(form.get("language") ?? "");
  const record = getCaseByToken(token);
  if (!record || !isLang(language)) redirect("/");
  const session = await getPatientSession();
  if (!session || session.mobileKey !== record.mobile_key) redirect(`/p/${token}`);
  setCaseLanguage(record.id, language);
  redirect(`/p/${token}/track`);
}

export async function patientLogout(form: FormData) {
  const token = String(form.get("token") ?? "");
  await clearPatientSession();
  redirect(token ? `/p/${token}` : "/");
}
