<template>
  <v-dialog v-model="show" max-width="680" persistent>
    <v-card class="d-flex flex-column" max-height="90vh">
      <v-toolbar flat color="grey-lighten-4">
        <v-row no-gutters class="fill-height px-6" align="center">
          <v-toolbar-title class="text-h6 font-weight-bold">
            {{
              props.mode === "edit"
                ? "Edit Schedule Task"
                : "Create Schedule Task"
            }}
          </v-toolbar-title>
          <v-spacer />
          <v-btn
            icon="mdi-close"
            variant="text"
            @click="close"
            :disabled="submitting"
          />
        </v-row>
      </v-toolbar>

      <v-card-text class="pa-4 flex-grow-1" style="overflow-y: auto">
        <v-form ref="formRef" v-model="valid">
          <v-row dense>
            <v-col cols="12">
              <InputLabel for="title" title="Title" required />
              <v-text-field
                id="title"
                v-model="subject"
                variant="outlined"
                density="comfortable"
                placeholder="Enter task title"
                hide-details="auto"
                class="mb-4"
              />
            </v-col>

            <v-col cols="12">
              <InputLabel for="date-range" title="Select Dates" required />
              <v-sheet border rounded class="pa-4 mb-4" color="grey-lighten-5">
                <v-date-picker
                  v-model="pickerDates"
                  multiple
                  :show-current="false"
                  color="primary"
                  elevation="0"
                  width="100%"
                  class="ma-0"
                />
                <v-divider class="my-3" />
                <div class="text-caption text-medium-emphasis mb-2">
                  {{ selectedDates.length }} date(s) selected
                </div>
                <div
                  v-if="selectedDates.length > 0"
                  class="d-flex flex-wrap ga-2"
                >
                  <v-chip
                    v-for="date in selectedDates"
                    :key="date"
                    size="small"
                    closable
                    @click:close="removeDate(date)"
                  >
                    {{ date }}
                  </v-chip>
                </div>
                <div v-else class="text-caption text-disabled">
                  No dates selected. Click on the calendar to select dates.
                </div>
              </v-sheet>
            </v-col>

            <v-col cols="12">
              <InputLabel for="schedule-time" title="Time" required />
              <v-text-field
                id="schedule-time"
                v-model="scheduleTime"
                type="time"
                variant="outlined"
                density="comfortable"
                hide-details="auto"
                prepend-inner-icon="mdi-clock-outline"
                class="mb-4"
              />
            </v-col>

            <v-col cols="12">
              <InputLabel for="selected-areas" title="Select Areas" required />
              <v-select
                id="selected-areas"
                v-model="selectedAreas"
                :items="areasList"
                item-title="name"
                item-value="value"
                return-object
                multiple
                variant="outlined"
                density="comfortable"
                :loading="loadingAreas"
                placeholder="Choose one or more areas"
                hide-details="auto"
                class="mb-4"
                chips
                closable-chips
              >
                <template v-slot:selection="{ item, index }">
                  <v-chip
                    v-if="index < 3"
                    size="small"
                    closable
                    @click:close="selectedAreas.splice(index, 1)"
                  >
                    {{ item.title }}
                  </v-chip>
                  <span
                    v-if="index === 3"
                    class="text-grey text-caption align-self-center"
                  >
                    (+{{ selectedAreas.length - 3 }} others)
                  </span>
                </template>
              </v-select>
            </v-col>

            <v-col v-if="selectedAreas.length > 0" cols="12">
              <InputLabel title="Units Under Selected Areas" />
              <v-card variant="outlined" rounded class="mb-4">
                <v-list density="compact" nav>
                  <template
                    v-for="(area, idx) in selectedAreas"
                    :key="area.value || area._id"
                  >
                    <v-divider v-if="idx > 0" />

                    <v-list-item
                      rounded="0"
                      class="px-3"
                      @click="toggleArea(area.value || area._id)"
                    >
                      <template #prepend>
                        <v-icon size="18" color="medium-emphasis">
                          {{
                            openAreas.includes(area.value || area._id)
                              ? "mdi-chevron-down"
                              : "mdi-chevron-right"
                          }}
                        </v-icon>
                      </template>

                      <v-list-item-title class="text-body-2 font-weight-medium">
                        {{ area.name }}
                      </v-list-item-title>

                      <template #append>
                        <v-progress-circular
                          v-if="
                            loadingUnits &&
                            !(area.value || area._id in fetchedAreaUnits)
                          "
                          size="14"
                          width="2"
                          indeterminate
                          color="primary"
                        />
                        <v-chip
                          v-else
                          size="x-small"
                          variant="tonal"
                          color="primary"
                        >
                          {{
                            (fetchedAreaUnits[area.value || area._id] || [])
                              .length
                          }}
                        </v-chip>
                      </template>
                    </v-list-item>

                    <v-expand-transition>
                      <div v-show="openAreas.includes(area.value || area._id)">
                        <v-card-text class="pt-1 pb-3 px-3">
                          <div
                            v-if="
                              loadingUnits &&
                              !(area.value || area._id in fetchedAreaUnits)
                            "
                            class="d-flex flex-wrap ga-2"
                          >
                            <v-skeleton-loader
                              v-for="n in 4"
                              :key="n"
                              type="chip"
                              width="80"
                            />
                          </div>

                          <div
                            v-else-if="
                              (fetchedAreaUnits[area.value || area._id] || [])
                                .length > 0
                            "
                            class="d-flex flex-wrap ga-1"
                          >
                            <v-chip
                              v-for="unit in fetchedAreaUnits[
                                area.value || area._id
                              ]"
                              :key="unit.unit"
                              size="small"
                              variant="tonal"
                            >
                              {{ unit.name }}
                            </v-chip>
                          </div>

                          <span v-else class="text-caption text-disabled">
                            No units configured
                          </span>
                        </v-card-text>
                      </div>
                    </v-expand-transition>
                  </template>
                </v-list>
              </v-card>
            </v-col>

            <v-col cols="12">
              <InputLabel for="description" title="Task Description" />
              <v-textarea
                id="description"
                v-model="description"
                variant="outlined"
                density="comfortable"
                rows="4"
                placeholder="Add additional details about this task..."
                hide-details="auto"
                class="mb-2"
              />
            </v-col>
          </v-row>
        </v-form>
      </v-card-text>

      <v-toolbar class="pa-0" density="compact">
        <v-row no-gutters>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="text"
              class="text-none"
              size="large"
              @click="close"
              height="48"
              :disabled="submitting"
            >
              Cancel
            </v-btn>
          </v-col>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="flat"
              color="primary"
              class="text-none font-weight-bold rounded-0"
              height="48"
              @click="submitTask"
              :loading="submitting"
            >
              {{ props.mode === "edit" ? "Save Changes" : "Add Schedule Task" }}
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
</template>

<script setup lang="ts">
import useAreas from "../composables/useAreas";
import useScheduleTask from "../composables/useScheduleTask";

const props = defineProps({
  mode: {
    type: String as PropType<"add" | "edit">,
    default: "add",
  },
  taskData: {
    type: Object,
    default: null,
  },
  site: {
    type: String,
    required: true,
  },
  serviceType: {
    type: String,
    default: "",
  },
});

const show = defineModel("show", { type: Boolean, default: false });
const emit = defineEmits(["saved", "close", "refresh"]);

const { getAreas, getAreaById } = useAreas();
const { createScheduleTask, updateScheduleTask, getScheduleTaskById } =
  useScheduleTask();

const formRef = ref<HTMLFormElement | null>(null);
const valid = ref(false);
const submitting = ref(false);
const loadingTask = ref(false);

const subject = ref("");
const description = ref("");
const scheduleTime = ref("08:00");
const pickerDates = ref<Date[]>([]);
const selectedDates = computed(() =>
  pickerDates.value.map((d) => toLocalISO(d)).sort()
);

const selectedAreas = ref<any[]>([]);
const loadingUnits = ref(false);
const fetchedAreaUnits = ref<Record<string, { name: string; unit: string }[]>>(
  {}
);
const openAreas = ref<string[]>([]);

const selectedAreaIds = computed(() =>
  selectedAreas.value.map((a: any) => a.value || a._id)
);

watch(selectedAreaIds, async (ids, prevIds) => {
  openAreas.value = ids.slice();

  const toFetch = ids.filter(
    (id) => !prevIds?.includes(id) && !(id in fetchedAreaUnits.value)
  );

  if (!toFetch.length) return;

  loadingUnits.value = true;
  try {
    await Promise.all(
      toFetch.map(async (id) => {
        try {
          const result = await getAreaById(id);
          fetchedAreaUnits.value[id] = result?.units || [];
        } catch {
          fetchedAreaUnits.value[id] = [];
        }
      })
    );
  } finally {
    loadingUnits.value = false;
  }
});

const message = ref("");
const messageSnackbar = ref(false);
const messageColor = ref("success");
const areasList = ref<any[]>([]);

const generateDateRange = (start: Date, end: Date): Date[] => {
  const dates: Date[] = [];
  const current = new Date(start);

  while (current <= end) {
    dates.push(new Date(current));
    current.setDate(current.getDate() + 1);
  }

  return dates;
};

const toLocalISO = (d: Date): string => {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
};

const removeDate = (dateISO: string) => {
  pickerDates.value = pickerDates.value.filter(
    (d) => toLocalISO(d) !== dateISO
  );
};

const showMessage = (text: string, color: string = "success") => {
  message.value = text;
  messageColor.value = color;
  messageSnackbar.value = true;
};

const toggleArea = (id: string) => {
  const idx = openAreas.value.indexOf(id);
  if (idx === -1) {
    openAreas.value.push(id);
  } else {
    openAreas.value.splice(idx, 1);
  }
};

const resetForm = () => {
  subject.value = "";
  description.value = "";
  scheduleTime.value = "08:00";
  pickerDates.value = [];
  selectedAreas.value = [];
  fetchedAreaUnits.value = {};
  openAreas.value = [];
};

const setFormFromTask = (task: any) => {
  if (!task) return;

  subject.value = task.title || "";
  description.value = task.description || "";
  scheduleTime.value = task.time || "08:00";

  const toISODate = (d: any) => {
    if (!d) return null;
    try {
      const dt = new Date(d);
      if (isNaN(dt.getTime())) return null;
      return dt.toISOString().slice(0, 10);
    } catch (e) {
      return null;
    }
  };

  // Handle dates array from task
  if (task.dates && Array.isArray(task.dates) && task.dates.length > 0) {
    pickerDates.value = task.dates.map((d: string) => new Date(d));
  } else if (task.startDate || task.endDate) {
    // Fallback for old format (startDate/endDate)
    const start = toISODate(task.startDate || task.start);
    const end = toISODate(task.endDate || task.end);
    if (start && end) {
      pickerDates.value = generateDateRange(new Date(start), new Date(end));
    }
  }

  selectedAreas.value = Array.isArray(task.areas)
    ? task.areas.map((area: any) => ({
        _id: area.value || area._id,
        name: area.name,
        value: area.value || area._id,
      }))
    : [];
};

const { data: getAreasReq, pending: loadingAreas } = await useLazyAsyncData(
  `get-areas-${props.site}`,
  () =>
    getAreas({ site: props.site, limit: 1000, serviceType: props.serviceType }),
  {
    watch: [show, () => props.site],
    immediate: false,
  }
);

watchEffect(() => {
  if (getAreasReq.value) {
    areasList.value = (getAreasReq.value?.items || []).map((item: any) => ({
      ...item,
      value: item._id || item.value,
    }));
  }
});

const loadTaskData = async () => {
  if (props.mode !== "edit") return;

  const id = (props.taskData as any)?._id || (props.taskData as any)?.id;

  if (!id) {
    if ((props.taskData as any)?.title) setFormFromTask(props.taskData);
    return;
  }

  loadingTask.value = true;
  try {
    const response = await getScheduleTaskById(id);

    if (response) {
      setFormFromTask(response as any);
    } else if ((props.taskData as any)?.title) {
      setFormFromTask(props.taskData);
    }
  } catch (error: any) {
    if ((props.taskData as any)?.title) setFormFromTask(props.taskData);
    showMessage(
      error?.data?.message || "Failed to load schedule task",
      "error"
    );
  } finally {
    loadingTask.value = false;
  }
};

const submitTask = async () => {
  submitting.value = true;
  try {
    const payload = {
      title: subject.value,
      time: scheduleTime.value,
      dates: selectedDates.value, // Array of YYYY-MM-DD strings
      description: description.value?.trim() || "",
      areas: selectedAreas.value.map((area: any) => ({
        name: area.name || area.title || "",
        value: area._id || area.value || area,
      })),
    };

    let response;

    if (props.mode === "edit" && props.taskData) {
      const taskId =
        (props.taskData as any)?._id || (props.taskData as any)?.id;
      response = await updateScheduleTask(taskId, payload);
    } else {
      response = await createScheduleTask({
        ...payload,
        site: props.site,
        serviceType: props.serviceType,
      });
    }

    showMessage(
      response?.message ||
        `Schedule task ${
          props.mode === "edit" ? "updated" : "created"
        } successfully`,
      "success"
    );

    emit("saved");
    emit("refresh");
    close();
  } catch (error: any) {
    showMessage(
      error?.data?.message || "Failed to submit schedule task",
      "error"
    );
  } finally {
    submitting.value = false;
  }
};

const close = () => {
  show.value = false;
  emit("close");
};

watch(
  [show, () => props.mode, () => props.taskData],
  async ([isOpen, mode, taskData]) => {
    if (isOpen && mode === "edit") {
      await loadTaskData();
    } else if (!isOpen) {
      resetForm();
    }
  },
  { immediate: false }
);
</script>
