<template>
  <q-page padding>
    <q-card
      flat
      bordered
      class="q-mb-xl"
    >
      <q-card-section class="row items-center justify-between q-gutter-md">
        <div class="text-h4">
          Mantis Tickets
        </div>
        <div class="row items-center q-gutter-sm">
          <!-- Filters -->
          <q-select
            dense
            outlined
            v-model="selectedStatus"
            :options="statusOptions"
            label="Status"
            clearable
            emit-value
            map-options
            style="min-width: 120px"
            @update:model-value="applyFilters"
          />
          <q-select
            dense
            outlined
            v-model="selectedPriority"
            :options="priorityOptions"
            label="Priority"
            clearable
            emit-value
            map-options
            style="min-width: 120px"
            @update:model-value="applyFilters"
          />
          <q-select
            dense
            outlined
            v-model="selectedSeverity"
            :options="severityOptions"
            label="Severity"
            clearable
            emit-value
            map-options
            style="min-width: 120px"
            @update:model-value="applyFilters"
          />
          <q-select
            dense
            outlined
            v-model="selectedReporter"
            :options="reporterOptions"
            label="Reporter"
            clearable
            emit-value
            map-options
            style="min-width: 150px"
            @update:model-value="applyFilters"
          />
          <!-- Search Input -->
          <q-input
            dense
            outlined
            debounce="300"
            v-model="searchTerm"
            placeholder="Search tickets..."
            @update:model-value="applyFilters"
            clearable
            style="width: 250px"
          >
            <template #append>
              <q-icon name="search" />
            </template>
          </q-input>
        </div>
      </q-card-section>

      <q-table
        :rows="tickets"
        :columns="columns"
        row-key="id"
        v-model:pagination="pagination"
        :loading="loading"
        @request="handleTableRequest"
        binary-state-sort
        flat
        bordered
        @row-click="onRowClick"
        class="cursor-pointer"
      >
        <template #body-cell-status="statusProps">
          <q-td :props="statusProps">
            <q-badge
              :color="getStatusColor(statusProps.row.status)"
              :label="statusProps.row.status"
              class="text-bold text-shadow text-subtitle2 text-uppercase"
            />
          </q-td>
        </template>
        <template #body-cell-priority="priorityProps">
          <q-td :props="priorityProps">
            <q-badge
              :color="getPriorityColor(priorityProps.row.priority)"
              :label="priorityProps.row.priority"
              class="text-bold text-shadow text-subtitle2 text-uppercase"
            />
          </q-td>
        </template>
        <template #body-cell-severity="severityProps">
          <q-td :props="severityProps">
            <q-badge
              :color="getSeverityColor(severityProps.row.severity)"
              :label="severityProps.row.severity"
              class="text-bold text-shadow text-subtitle2 text-uppercase"
            />
          </q-td>
        </template>
        <template #body-cell-actions="actionsProps">
          <q-td
            :props="actionsProps"
            class="text-center"
          >
            <q-btn
              size="md"
              color="info"
              icon="summarize"
              round
              flat
              @click.stop="showTicketSummary(actionsProps.row.id)"
              :title="'Show summary for ticket ' + actionsProps.row.id"
            />
          </q-td>
        </template>
      </q-table>
    </q-card>

    <mantis-ticket-dialog
      v-model="showDialog"
      :ticket-id="selectedTicketId"
      @close="closeDialog"
    />

    <!-- New Summary Dialog -->
    <q-dialog
      v-model="showSummaryDialog"
    >
      <q-card
        style="max-width: max(75%, 500px)"
      >
        <q-card-section class="row items-center q-pb-none q-mb-md">
          <div class="text-h4">
            Summary for Ticket #{{ summaryTicketId }}
          </div>
          <q-space />
          <q-btn
            icon="close"
            flat
            round
            dense
            v-close-popup
          />
        </q-card-section>
        <q-separator />

        <q-card-section class="summary-content">
          <div v-html="summaryContent" />
        </q-card-section>
      </q-card>
    </q-dialog>
  </q-page>
</template>

<script setup>
import { ref, onMounted, watch, defineProps } from 'vue';
import { useRouter } from 'vue-router';
import axios from 'axios';
import { useQuasar } from 'quasar';
import MantisTicketDialog from 'src/components/MantisTicketDialog.vue';
import { marked } from 'marked';

const props = defineProps({
  ticketId: {
    type: [String, Number],
    'default': null
  }
});

const $q = useQuasar();
const tickets = ref([]);
const loading = ref(false);
const searchTerm = ref('');
const showDialog = ref(false);
const selectedTicketId = ref(null);
const showSummaryDialog = ref(false); // New state for summary dialog
const summaryContent = ref(''); // New state for summary content
const summaryTicketId = ref(null); // New state for summary ticket ID

// Filter refs
const selectedStatus = ref(null);
const selectedPriority = ref(null);
const selectedSeverity = ref(null);
const selectedReporter = ref(null);
const statusOptions = ref([]);
const priorityOptions = ref([]);
const severityOptions = ref([]);
const reporterOptions = ref([]);

const router = useRouter();

const pagination = ref({
  sortBy: 'updatedAt',
  descending: true,
  page: 1,
  rowsPerPage: 25,
  rowsNumber: 0 // Total number of rows/tickets
});

const columns = [
  { name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
  { name: 'title', label: 'Title', field: 'title', align: 'left', sortable: true },
  { name: 'status', label: 'Status', field: 'status', align: 'center', sortable: true },
  { name: 'priority', label: 'Priority', field: 'priority', align: 'center', sortable: true },
  { name: 'severity', label: 'Severity', field: 'severity', align: 'center', sortable: true },
  { name: 'reporterUsername', label: 'Reporter', field: 'reporterUsername', align: 'left', sortable: true },
  { name: 'updatedAt', label: 'Last Updated', field: 'updatedAt', align: 'left', sortable: true, format: (val) => new Date(val).toLocaleString() },
  { name: 'actions', label: 'Actions', field: 'id', align: 'center' },
];

// Fetch distinct filter values
const fetchFilterOptions = async() =>
{
  try
  {
    const [statusRes, priorityRes, severityRes, reporterRes] = await Promise.all([
      axios.get('/api/mantis/filters/statuses'),
      axios.get('/api/mantis/filters/priorities'),
      axios.get('/api/mantis/filters/severities'),
      axios.get('/api/mantis/filters/reporters')
    ]);

    // Format options for q-select
    const formatOptions = (data) => data.map(value => ({ label: value, value }));

    statusOptions.value = formatOptions(statusRes.data);
    priorityOptions.value = formatOptions(priorityRes.data);
    severityOptions.value = formatOptions(severityRes.data);
    reporterOptions.value = formatOptions(reporterRes.data);
  }
  catch (error)
  {
    console.error('Error fetching filter options:', error);
    $q.notify({
      type: 'negative',
      message: 'Failed to load filter options.'
    });
  }
};

const fetchTickets = async(page = pagination.value.page) =>
{
  loading.value = true;
  try
  {
    const params = {
      page: page,
      limit: pagination.value.rowsPerPage,
      search: searchTerm.value || undefined,
      sortBy: pagination.value.sortBy, // Add sortBy
      sortOrder: pagination.value.descending ? 'desc' : 'asc', // Add sortOrder
      // Add filter parameters
      status: selectedStatus.value || undefined,
      priority: selectedPriority.value || undefined,
      severity: selectedSeverity.value || undefined,
      reporterUsername: selectedReporter.value || undefined,
    };
    // Remove undefined params
    Object.keys(params).forEach(key => params[key] === undefined && delete params[key]);

    const response = await axios.get('/api/mantis', { params });
    tickets.value = response.data.data;
    pagination.value.rowsNumber = response.data.pagination.total;
    pagination.value.page = response.data.pagination.page; // Update current page
  }
  catch (error)
  {
    console.error('Error fetching Mantis tickets:', error);
    $q.notify({
      type: 'negative',
      message: 'Failed to fetch Mantis tickets.'
    });
  }
  finally
  {
    loading.value = false;
  }
};

// Function to apply filters and reset pagination
const applyFilters = () =>
{
  pagination.value.page = 1; // Reset to first page when filters change
  fetchTickets();
};

const handleTableRequest = (props) =>
{
  const { page, rowsPerPage, sortBy, descending } = props.pagination;
  pagination.value.page = page;
  pagination.value.rowsPerPage = rowsPerPage;
  pagination.value.sortBy = sortBy;
  pagination.value.descending = descending;
  fetchTickets(page);
};

const onRowClick = (evt, row) =>
{
  //Change the route
  router.push({ name: 'mantis', params: { ticketId: row.id } });
};

const openDialogForTicket = (id) =>
{
  const ticketNum = Number(id);
  if (!isNaN(ticketNum) && ticketNum > 0)
  {
    selectedTicketId.value = ticketNum;
    showDialog.value = true;
  }
};

const closeDialog = () =>
{
  showDialog.value = false;
  selectedTicketId.value = null;

  //Reset the route to remove the ticketId from the URL
  router.push({ name: 'mantis' });
};

// Watch for changes in the ticketId prop
watch(() => props.ticketId, (newTicketId) =>
{
  if (newTicketId)
  {
    openDialogForTicket(newTicketId);
  }
  else
  {
    closeDialog();
  }
});

onMounted(() =>
{
  fetchFilterOptions(); // Fetch filter options on mount
  fetchTickets();
  // Check initial prop value on mount
  if (props.ticketId)
  {
    openDialogForTicket(props.ticketId);
  }
});

// Helper functions for badge colors (customize as needed)
const getStatusColor = (status) =>
{
  const lowerStatus = status?.toLowerCase();
  if (lowerStatus === 'new') return 'blue';
  if (lowerStatus === 'feedback') return 'orange';
  if (lowerStatus === 'acknowledged') return 'purple';
  if (lowerStatus === 'confirmed') return 'cyan';
  if (lowerStatus === 'assigned') return 'teal';
  if (lowerStatus === 'resolved') return 'green';
  if (lowerStatus === 'closed') return 'grey';
  return 'primary';
};

const getPriorityColor = (priority) =>
{
  const lowerPriority = priority?.toLowerCase();
  if (lowerPriority === 'none') return 'grey';
  if (lowerPriority === 'low') return 'blue';
  if (lowerPriority === 'normal') return 'green';
  if (lowerPriority === 'high') return 'orange';
  if (lowerPriority === 'urgent') return 'red';
  if (lowerPriority === 'immediate') return 'purple';
  return 'primary';
};

const getSeverityColor = (severity) =>
{
  const lowerSeverity = severity?.toLowerCase();
  if (lowerSeverity === 'feature') return 'info';
  if (lowerSeverity === 'trivial') return 'grey';
  if (lowerSeverity === 'text') return 'blue-grey';
  if (lowerSeverity === 'tweak') return 'light-blue';
  if (lowerSeverity === 'minor') return 'lime-9';
  if (lowerSeverity === 'major') return 'amber';
  if (lowerSeverity === 'crash') return 'deep-orange';
  if (lowerSeverity === 'block') return 'red';
  return 'primary';
};

// Function to fetch and display ticket summary
const showTicketSummary = async(ticketId) =>
{
  $q.loading.show({
    message: 'Generating Ticket Summary...',
    // spinner: QSpinnerGears,
    spinnerColor: 'white'
  });
  if (!ticketId)
  {
    $q.loading.hide(); // Hide loading if no ticketId
    return;
  }
  try
  {
    const response = await axios.get(`/api/mantis/summary/${ticketId}`);

    // Store summary data and show the dialog
    summaryContent.value = marked(response.data?.summary || 'No summary available');
    //Turn anything surrounded by `[]` into a span with a class of "label"
    summaryContent.value = summaryContent.value.replace(/\[(.*?)\]/g, '<span class="label">[$1]</span>');
    summaryTicketId.value = ticketId;
    showSummaryDialog.value = true;
  }
  catch (error)
  {
    console.error('Error fetching ticket summary:', error);
    $q.notify({
      type: 'negative',
      message: `Failed to fetch summary for ticket #${ticketId}: ${error.response?.data?.message || error.message}`
    });
  }
  finally
  {
    $q.loading.hide();
  }
};

</script>

<style scoped>
/* Add any specific styles here */
.summary-content:deep(h6) {
  margin: 0;
}

.summary-content:deep(span.label) {
  font-family: monospace;
}

.summary-content:deep(span.label):after {
  content: ' - ';
}
</style>
