<template>
  <el-dialog append-to=".layout-main .content-wrapper" :title="site ? TEXT.modules.adminSites.editTitle : TEXT.modules.adminSites.newTitle" width="520px" v-model="visibleProxy" :close-on-click-modal="false">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
      <el-form-item :label="TEXT.common.fields.siteName" prop="name">
        <el-input v-model="form.name" :placeholder="TEXT.common.placeholders.input + TEXT.common.fields.siteName" />
      </el-form-item>
      <el-form-item :label="TEXT.common.fields.city" prop="city">
        <el-input v-model="form.city" :placeholder="TEXT.modules.adminSites.cityPlaceholder" />
      </el-form-item>
      <el-form-item :label="TEXT.modules.adminSites.piLabel" prop="pi_name">
        <el-input v-model="form.pi_name" :placeholder="TEXT.modules.adminSites.piPlaceholder" />
      </el-form-item>
      <el-form-item :label="TEXT.common.fields.phone" prop="phone">
        <el-input v-model="form.phone" :placeholder="TEXT.modules.adminSites.phonePlaceholder" />
      </el-form-item>
      <el-form-item :label="TEXT.common.fields.contact" prop="contact">
        <el-select
          v-model="form.craSelections"
          multiple
          filterable
          :placeholder="TEXT.modules.adminSites.contactPlaceholder"
        >
          <el-option
            v-for="user in craOptions"
            :key="user.value"
            :label="user.label"
            :value="user.value"
          />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="visibleProxy = false">{{ TEXT.common.actions.cancel }}</el-button>
      <el-button type="primary" :loading="submitting" @click="onSubmit">{{ TEXT.common.actions.save }}</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { createSite, updateSite } from "../../api/sites";
import type { Site } from "../../types/api";
import { useAuthStore } from "../../store/auth";
import { evaluateAction } from "../../guards/actionGuard";
import { logAudit } from "../../audit";
import { TEXT, requiredMessage } from "../../locales";

const props = defineProps<{
  visible: boolean;
  studyId: string;
  site?: Site | null;
  members?: any[];
  users?: any[];
}>();

const emit = defineEmits<{
  (e: "update:visible", value: boolean): void;
  (e: "saved"): void;
}>();

const visibleProxy = computed({
  get: () => props.visible,
  set: (val: boolean) => emit("update:visible", val),
});

const auth = useAuthStore();
const formRef = ref<FormInstance>();
const submitting = ref(false);
const form = reactive({
  name: "",
  city: "",
  pi_name: "",
  phone: "",
  contact: "",
  craSelections: [] as string[],
  is_active: true,
});

const rules = reactive<FormRules>({
  name: [{ required: true, message: requiredMessage(TEXT.common.fields.siteName), trigger: "blur" }],
});

const craOptions = computed(() => {
  const userMap = (props.users || []).reduce<Record<string, string>>((acc, cur: any) => {
    if (cur?.id) acc[cur.id] = cur.full_name || cur.username || cur.id;
    return acc;
  }, {});
  return (props.members || []).map((m: any) => ({
    label: userMap[m.user_id] || m.full_name || m.username || m.user_id,
    value: m.user_id,
  }));
});

const resetForm = () => {
  form.name = "";
  form.city = "";
  form.pi_name = "";
  form.phone = "";
  form.contact = "";
  form.craSelections = [];
  form.is_active = true;
};

watch(
  () => props.visible,
  (val) => {
    if (val) {
      resetForm();
      if (props.site) {
        form.name = props.site.name;
        form.city = props.site.city || "";
        form.pi_name = props.site.pi_name || "";
        form.phone = (props.site as any)?.contact_phone || (props.site as any)?.phone || "";
        form.contact = props.site.contact || "";
        const rawSelections = (props.site.contact || "")
          .split(",")
          .map((s) => s.trim())
          .filter(Boolean);
        const optionByLabel: Record<string, string> = {};
        craOptions.value.forEach((opt) => {
          optionByLabel[opt.label] = opt.value;
        });
        form.craSelections = rawSelections.map((s) => optionByLabel[s] || s);
        form.is_active = props.site.is_active;
      }
    }
  }
);

const onSubmit = async () => {
  if (!formRef.value) return;
  const decision = evaluateAction({
    actorRole: auth.user?.role || null,
    requiredPermission: "site.manage",
    target: { siteId: props.site?.id, studyId: props.studyId },
  });
  if (!decision.allowed) {
    ElMessage.warning(decision.reason || TEXT.common.messages.noPermission);
    logAudit(decision.auditType, {
      targetId: props.site?.id || props.studyId,
      targetName: props.site?.name,
      reason: decision.reason,
      severity: decision.severity,
    });
    return;
  }
  await formRef.value.validate();
  submitting.value = true;
  try {
    const contact = form.craSelections.length ? form.craSelections.join(",") : form.contact;
    if (props.site) {
      await updateSite(props.studyId, props.site.id, {
        name: form.name,
        city: form.city,
        pi_name: form.pi_name,
        contact,
        is_active: form.is_active,
      });
      ElMessage.success(TEXT.modules.adminSites.updateSuccess);
      logAudit("SITE_STATUS_CHANGED", {
        targetId: props.site.id,
        targetName: props.site.name,
        after: { name: form.name, is_active: form.is_active },
        severity: "normal",
      });
    } else {
      await createSite(props.studyId, {
        name: form.name,
        city: form.city,
        pi_name: form.pi_name,
        contact,
      });
      ElMessage.success(TEXT.modules.adminSites.createSuccess);
      logAudit("SITE_STATUS_CHANGED", {
        targetId: props.studyId,
        targetName: form.name,
        after: { name: form.name },
        severity: "normal",
      });
    }

    emit("saved");
    visibleProxy.value = false;
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.saveFailed);
    logAudit("SITE_STATUS_CHANGED", {
      targetId: props.site?.id || props.studyId,
      targetName: props.site?.name || form.name,
      after: { name: form.name },
      severity: "warning",
      reason: e?.response?.data?.message,
    });
  } finally {
    submitting.value = false;
  }
};
</script>
