<script setup>
import {defineProps, onMounted, ref, watch} from 'vue';
import {SessionUser} from "@/components/session/token/SessionUser.vue";
import ColorIndicator from "@/components/displays/buttons/ColorIndicator.vue";
import ActionSettingsWheelButton from "@/components/displays/buttons/ActionSettingsWheelButton.vue";
import ActionSettingsWheelItem from "@/components/displays/buttons/ActionSettingsWheelItem.vue";
import { createOrderItem, getOrderItems } from "@/components/shop/OrdersItems.vue";
import Swal from "sweetalert2";
import ActionSettingsWheelItemLabel from "@/components/displays/buttons/ActionSettingsWheelItemLabel.vue";

const props = defineProps({
  reg: {
    type: String,
    default: null,
  },
  dateFrom: {
    type: Date,
    default: () => null,
  },
});

/** Dynamic variables */
const usageLog = ref(null);
const xlvask_vehicle_types = ref(null);
const product_options = ref(null);
const departments = ref(null);
const related_orders = ref(null);

const getUsageLog = async () => {
  SessionUser.superUser.modules.xlvask.functions.getUsageLog(
      (props.dateFrom === null ? null : SessionUser.superUser.modules.xlvask.functions.convertDateTimeToISO(props.dateFrom)),
      props.reg,
  ).then(
      (response) => {
        if (response.status === 200) {
          console.log("Usage log response:", response);
          usageLog.value = response.data.data;
        } else {
          console.error("Error fetching usage log:", response);
        }
      }
  ).catch(
      (error) => {
        console.error("Error fetching usage log:", error);
      }
  );
};

const getVehicleTypes = async () => {
  SessionUser.superUser.modules.xlvask.functions.getVehicleTypes().then(
      (response) => {
        if (response.status === 200) {
          console.log("Vehicle types response:", response);
          xlvask_vehicle_types.value = response.data.data;
        } else {
          console.error("Error fetching vehicle types:", response);
        }
      }
  ).catch(
      (error) => {
        console.error("Error fetching vehicle types:", error);
      }
  );
};

const getProductOptions = async () => {
  if (product_options.value === null) {
    SessionUser.objects.product_options.get.all().then((result) => {
      product_options.value = result;
    });
  }
}

const getDepartments = async () => {
  SessionUser.objects.departments.get.all().then((result) => {
    departments.value = result;
  });
}

const getRelatedOrders = async () => {
  SessionUser.superUser.modules.xlvask.functions.getRelatedOrders(listWashIds()).then(
      (response) => {
        if (response.status === 200) {
          console.log("Related orders response:", response);
          related_orders.value = response.data.data;
        } else {
          console.error("Error fetching related orders:", response);
        }
      }
  ).catch(
      (error) => {
        console.error("Error fetching related orders:", error);
      }
  );
};

// Watch for changes in the usage log and update the related orders
watch(usageLog, (newValue) => {
  if (newValue) {
    console.log("Usage log changed:", newValue);
    getRelatedOrders();
  }
});

const listWashIds = () => {
  let washIds = [];
  if (usageLog.value) {
    for (const usage of usageLog.value) {
      washIds.push(usage.WashId);
    }
  }
  return washIds;
}

const example = {
  "WashId": "892ae789-aeea-4bda-9374-cf931290aefd",
  "CustomerId": "59440200",
  "Customer": "DITOBUS EXCURSIONS A/S",
  "VatNumber": "31171520",
  "Location": "Hvidovre",
  "Hall": "Hvidovre_1",
  "HallId": "845d29a1-a7d2-4e3b-bbc3-2b13242d744a",
  "StartTime": "2024-01-26T14:46:53.067",
  "FinishTime": "2024-01-26T14:54:08.653",
  "RegistrationNumber": "BJ22227",
  "VehicleType": "Bus/autocamper, M",
  "IdentificationType": "LPR",
  "IdentificationId": "BJ22227",
  "Info": "BJ22227",
  "Updated": "",
  "Prepaid": false,
  "FinishStatus": 1,
  "CustomerGuid": "21ba156a-b2d2-44be-8398-4b67d66003d6",
  "VehicleId": "0584ef66-3deb-491e-9b82-0a28cfc20e9e",
  "WashItems": [
    {
      "WashItemId": "399b25c1-5c03-4f25-b5e9-00731e9b94c4",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "Ikke HT dysebom bag",
      "Unit": "stk",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    },
    {
      "WashItemId": "ef3ca812-bbe5-4cf3-916f-06fd17c04225",
      "ExternalProductId": null,
      "ExternalProductName": "Spot Free",
      "OriginalProductName": "Skylning med RO",
      "Unit": "stk",
      "UnitPrice": 35,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 35,
      "Vat": 3.06,
      "PriceIncVat": 15.31
    },
    {
      "WashItemId": "5c4ec0d9-cffc-45eb-9213-406dbcb8c975",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "2-børstevask",
      "Unit": "stk",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    },
    {
      "WashItemId": "f7bd7404-f5a3-4a59-8e85-53b284df3260",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "Halleje",
      "Unit": "min",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    },
    {
      "WashItemId": "6dba6c24-8191-4c2b-913c-7366518fb41d",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "Stor bil",
      "Unit": "stk",
      "UnitPrice": 559,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 559,
      "Vat": 48.91,
      "PriceIncVat": 244.56
    },
    {
      "WashItemId": "61d11d87-2ee4-4a4d-890b-a0870ae1a924",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "HT sider",
      "Unit": "stk",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    },
    {
      "WashItemId": "ec6eb1c4-b58c-457f-8224-b674cf41dc29",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "EU spejl",
      "Unit": "stk",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    },
    {
      "WashItemId": "54b4deec-be3e-4cb2-b68d-b9af9cff6fcf",
      "ExternalProductId": null,
      "ExternalProductName": null,
      "OriginalProductName": "HT chassis",
      "Unit": "stk",
      "UnitPrice": 0,
      "Count": 1,
      "Discount": 65,
      "PriceExVat": 0,
      "Vat": 0,
      "PriceIncVat": 0
    }
  ]
}
const exampleVehicleTypes = [
  {
    "id": 1,
    "vehicleTypeId": "0f915576-587c-4494-bcce-388b3b3fe55a",
    "product": 17,
    "name": "Bus/autocamper, M",
    "created_at": "2025-05-19 09:41:20",
    "updated_at": "2025-05-19 09:41:20"
  },
  {
    "id": 2,
    "vehicleTypeId": "e2638c21-366d-4b7f-b0af-eb3634ae2c8c",
    "product": 15,
    "name": "Kassevogn/Varevogn, L",
    "created_at": "2025-05-19 09:44:39",
    "updated_at": "2025-05-19 09:44:39"
  },
  {
    "id": 3,
    "vehicleTypeId": "5e6cfa13-df14-4a11-8d3d-603a41d37f68",
    "product": 17,
    "name": "Bus/autocamper, L",
    "created_at": "2025-05-19 10:12:54",
    "updated_at": "2025-05-19 10:12:54"
  }
];
onMounted(() => {
  getVehicleTypes();
  getUsageLog();
  getProductOptions();
  getDepartments();
});

const getProductName = (item) => {
  if (item.ExternalProductName) {
    return item.ExternalProductName;
  } else if (item.OriginalProductName) {
    return item.OriginalProductName;
  } else {
    return "Unknown Product Name " + item.WashItemId;
  }
};


const getOrderFromUsageLogEntry = (usageLogEntry) => {
  return {
    customer_id: usageLogEntry.CustomerId,
    reg_1: usageLogEntry.RegistrationNumber,
    reg_2: "",
    reg_3: "",
    wash_id: usageLogEntry.WashId,
  }
}

const getPrimaryServiceProductId = (usageLogEntry) => {
  // Check if the vehicle type is in the list
  const vehicleType = xlvask_vehicle_types.value.find(type => type.name === usageLogEntry.VehicleType);
  if (vehicleType) {
    // If the vehicle type is found, return the product ID
    return vehicleType.product;
  } else {
    // If the vehicle type is not found, return null
    return null;
  }
}


const recognizedItems = {
  "Undervognskylning": {
    getProductId: (usageLogEntry) => {
      let primaryProductId = getPrimaryServiceProductId(usageLogEntry);
      // Get all the matching options where the product id is the same as the primary product id
      let options = product_options.value.filter(option => option.product_id === primaryProductId);
      // Check if any options have the option_id 21
      let option = options.find(option => option.option_id === 21);
      if (option) {
        // If the option is found, return the option_id (21)
        return option.option_id;
      } else {
        // If the option is not found, return null
        return null;
      }
    }
  },
  // Spot Free
  "Skylning med RO": {
    getProductId: (usageLogEntry) => {
      let primaryProductId = getPrimaryServiceProductId(usageLogEntry);
      // Get all the matching options where the product id is the same as the primary product id
      let options = product_options.value.filter(option => option.product_id === primaryProductId);
      // Check if any options have the option_id 23, or 24
      let option = options.find(option => option.option_id === 23 || option.option_id === 24);
      if (option) {
        // If the option is found, return the option_id (23 or 24)
        return option.option_id;
      } else {
        // If the option is not found, return null
        return null;
      }
    }
  },
  // Primary services
  "Stor bil": {
    getProductId: (usageLogEntry) => {
      // Check if the vehicle type is in the list
      return getPrimaryServiceProductId(usageLogEntry);
    }
  },
  "Lille bil": {
    getProductId: (usageLogEntry) => {
      // Check if the vehicle type is in the list
      return getPrimaryServiceProductId(usageLogEntry);
    }
  },
}

const round_price_down = (price) => {
  // Round the price down to the nearest whole number
  return Math.floor(price);
}

const getOrderItemsFromUsageLogEntry = (usageLogEntry) => {
  let items = [];
  let unrecognizedItems = [];
  // Filter out all the free items
  const filteredItems = usageLogEntry.WashItems.filter(item => item.PriceIncVat > 0);
  // If the "Stor bil" item is present, set it to be the first item
  const storBilIndex = filteredItems.findIndex(item => item.OriginalProductName === "Stor bil" || item.OriginalProductName === "Lille bil");
  if (storBilIndex > -1) {
    const storBilItem = filteredItems.splice(storBilIndex, 1)[0];
    filteredItems.unshift(storBilItem);
  }
  // Loop through the filtered items
  for (const item of filteredItems) {
    // Check if the item is recognized
    if (recognizedItems[item.OriginalProductName]) {
      items.push({
        product_id: recognizedItems[item.OriginalProductName].getProductId(usageLogEntry),
        quantity: item.Count,
        discount_percentage: item.Discount,
        price: {
          unit: round_price_down(item.UnitPrice), // Before discount
          each: round_price_down( item.UnitPrice - (item.UnitPrice * item.Discount / 100) ), // One item after discount
          total: round_price_down( (item.UnitPrice * item.Count) - (item.UnitPrice * item.Count * item.Discount / 100) ), // Total price after discount x quantity
        }
      });
    } else {
      // If the item is not recognized, add it to the unrecognized items
      unrecognizedItems.push(item);
    }
  }
  // Calculate the total price
  let price = {
    total: 0,
  }
  for (const item of items) {
    price.total += item.price.total;
  }
  return { items, unrecognizedItems, price };
}

const onClickCreateOrder = async (usageLogEntry) => {
  // Check if the order can be created
  if (!canCreateOrder(usageLogEntry)) {
    console.error("Cannot create order: unrecognized items present.");
    return;
  }
  let order = getOrderFromUsageLogEntry(usageLogEntry);
  let orderItems = getOrderItemsFromUsageLogEntry(usageLogEntry);
  // Create the order
  let order_props = {
    customer_id: parseInt(order.customer_id),
    cashier_id: null,
    department_id: getDepartmentId(usageLogEntry),
    reference: null,
    reg_1: order.reg_1,
    reg_2: order.reg_2,
    reg_3: order.reg_3,
    notes: null,
    invoice_collection_id: null,
  }
  await SessionUser.objects.orders
      .add(
          order_props.customer_id,
          order_props.cashier_id,
          order_props.department_id,
          order_props.reference,
          order_props.reg_1,
          order_props.reg_2,
          order_props.reg_3,
          order_props.notes,
          order_props.invoice_collection_id,
      ).then(
          async (response) => {
            if (response.status === 200) {
              let orderId = parseInt(response.data.data.id);
              console.log("Order created successfully:", response);
              // Add the wash id to the order
              await SessionUser.objects.orders.set.wash_id(orderId, usageLogEntry.WashId);
              // Set the time created to the start time
              await SessionUser.objects.orders.set.created_at(orderId, SessionUser.functions.date.format(SessionUser.superUser.modules.xlvask.functions.convertISODateTimeToDate(usageLogEntry.StartTime)));
              let relational_id = null;
              // Add the order items to the order
              for (const item of orderItems.items) {
                console.log("Creating order item:", item, "to order:", orderId);
                await createOrderItem(
                    orderId,
                    item.product_id,
                    item.quantity,
                    relational_id,
                    null,
                    item.price.each
                ).then(
                    (response) => {
                      if (response.status === 200) {
                        console.log("Order item created successfully:", response);
                        // If the relational_id is null, set it to the order item id
                        if (relational_id === null) {
                          relational_id = parseInt(response.data.data.id);
                          console.log("Setting relational id to:", relational_id);
                        }
                      } else {
                        console.error("Error creating order item:", response);
                      }
                    }
                ).catch(
                    (error) => {
                      console.error("Error creating order item:", error);
                    }
                )
              }
              onOrderCreated(orderId);
            } else {
              console.error("Error creating order:", response);
            }
          }
      ).catch(
          (error) => {
            console.error("Error creating order:", error);
          }
      );
  // Add the order items to the order
  console.log("Creating order:", order_props);
  console.log("Order items:", orderItems.items);
}

const onOrderCreated = (orderId) => {
  Swal.fire({
    title: "Order created",
    text: "Order ID: " + orderId,
    icon: "success",
    confirmButtonText: "OK"
  });
  // Load the related orders
  getRelatedOrders();
}

const hasUnrecognizedItems = (usageLogEntry) => {
  let orderItems = getOrderItemsFromUsageLogEntry(usageLogEntry);
  return orderItems.unrecognizedItems.length > 0;
}

const hasUnrecognizedDepartment = (usageLogEntry) => {
  // Check if the department is in the list
  const department = getDepartmentId(usageLogEntry);
  return ( department === null || department === undefined );
}

const listRelatedOrders = (usageLogEntry) => {
  // Check if the order is already created (If the wash id key is present in the related orders)
  if (related_orders.value) {
    let keys = Object.keys(related_orders.value);
    if (keys.includes(usageLogEntry.WashId)) {
      return related_orders.value[usageLogEntry.WashId];
    }
  }
}

const hasRelatedOrder = (usageLogEntry) => {
  // Check if the order is already created (If the wash id key is present in the related orders)
  /**
   * {
   *     "892ae789-aeea-4bda-9374-cf931290aefd": [
   *         9997, // Order ID
   *         9998, // Order ID #2 (If multiple orders are related)
   *     ]
   * }
   */
  return listRelatedOrders(usageLogEntry) !== undefined && listRelatedOrders(usageLogEntry).length > 0;
}

const canCreateOrder = (usageLogEntry) => {
  // Check if there are any unrecognized items, and if the department is recognized
  return (
      !hasUnrecognizedItems(usageLogEntry) &&
      !hasUnrecognizedDepartment(usageLogEntry) &&
      !hasRelatedOrder(usageLogEntry)
  );
}

const getDepartmentId = (usageLogEntry) => {
  // Check if the department is in the list
  const department = departments.value.find(department => department.name === usageLogEntry.Location);
  if (department) {
    // If the department is found, return the department id
    return parseInt(department.id);
  } else {
    // If the department is not found, return null
    return null;
  }
}

const redirectDepartmentOrderPage = async (orderId) => {
  // Send the user to the order page (In a new tab)
  // Get the department id from the order
  await SessionUser.objects.orders.functions.get_department_id(orderId).then((response) => {
    // Get the department id from the response
    // Send the user to the order page (In a new tab)
    window.open(`/admin/${response}/modules/pos/orders/${orderId}`, '_blank');
  }).catch((error) => {
    console.error(error);
  });
};

const getUsageStatus = (usageLogEntry) => {
  let result = {
    color_class: "has-text-grey",
    price: {
      total: 0,
    }
  }
  if (hasRelatedOrder(usageLogEntry)) {
    result.color_class = "has-text-success";
  }
  if (hasUnrecognizedItems(usageLogEntry)) {
    result.color_class = "has-text-danger";
  }
  if (hasUnrecognizedDepartment(usageLogEntry)) {
    result.color_class = "has-text-warning";
  }
  // Add the price to the result
  result.price = getOrderItemsFromUsageLogEntry(usageLogEntry).price;
  return result;
}

const onClickCreateOrderAllApplicable = async () => {
  // Loop through all the usage log entries
  for (const usageLogEntry of usageLog.value) {
    // Check if the order can be created
    if (canCreateOrder(usageLogEntry)) {
      await onClickCreateOrder(usageLogEntry);
    }
  }
}

</script>

<template>
  <h1>XLVask Usage Log</h1>
  <div class="buttons">
    <button class="button is-primary" @click="onClickCreateOrderAllApplicable">Create Order for All Applicable</button>
    <button class="button is-info" @click="getUsageLog">Refresh</button>
  </div>
  <table class="table mb-6">
    <!-- Table header -->
    <thead>
      <tr>
        <th class="is-narrow"><!-- Status --></th>
        <th>Customer</th>
        <th>Registration Number</th>
        <th>Price</th>
        <th>Start Time</th>
        <th>End Time</th>
        <th>Location</th>
        <th><!-- Actions --></th>
      </tr>
    </thead>
    <!-- Table body -->
    <tbody>
      <template v-for="(usage, index) in usageLog" :key="index">
        <tr>
          <td>
            <ColorIndicator
              v-bind:color_class="getUsageStatus(usage).color_class"
              v-bind:visibility="{
                icon: true,
                dropdown: false
              }"
              @onClick="() => {console.log('Clicked', usage)}"
              />
          </td>
          <td>{{ usage.CustomerId }}</td>
          <td>{{ usage.RegistrationNumber }}</td>
          <td>
            <ColorIndicator
              v-bind:color_class="getUsageStatus(usage).color_class"
              v-bind:visibility="{
                icon: false,
                dropdown: true
              }"
              v-bind:label="{
                text: SessionUser.functions.currency.toLocal(getUsageStatus(usage).price.total),
                classes: []
              }"
              v-bind:dropdown_content="{
                  content: [
                      {
                        text: 'Services',
                        button: false,
                        action: () => {},
                      },
                      ...(getOrderItemsFromUsageLogEntry(usage).items.map(item => {
                        return {
                          text: `${SessionUser.objects.products.functions.getProductName(item.product_id)} - ${item.quantity} x ${SessionUser.functions.currency.toLocal(item.price.each)}`,
                          button: true,
                          action: () => {},
                          button_text: SessionUser.functions.currency.toLocal(item.price.total),
                          v_centered: true,
                        }
                      })),
                      ...(getOrderItemsFromUsageLogEntry(usage).unrecognizedItems.map(item => {
                        return {
                          text: `${item.OriginalProductName} - ${item.Count} x ${SessionUser.functions.currency.toLocal(item.UnitPrice)}`,
                          button: true,
                          action: () => {},
                          icon: 'fas fa-exclamation-triangle',
                          button_text: SessionUser.functions.currency.toLocal(item.PriceIncVat),
                          v_centered: true,
                        }
                      }))
                  ]
              }"
              />
          </td>
          <td>{{ usage.StartTime }}</td>
          <td>{{ usage.FinishTime }}</td>
          <td>
            <ColorIndicator
              v-bind:color_class="getUsageStatus(usage).color_class"
              v-bind:visibility="{
                icon: false,
                dropdown: false
              }"
              v-bind:label="{
                text: usage.Location,
                classes: []
              }"
              v-bind:dropdown_content="{
                  content: [
                      {
                        text: 'Bane',
                        button: true,
                        button_text: usage.Hall,
                        action: () => {},
                        v_centered: true,
                      }
                  ]
              }"
              />
          </td>
          <td>
            <ActionSettingsWheelButton>
              <template #actions>
                <!-- Create order based on usage log entry -->
                <ActionSettingsWheelItem
                  label="Create Order"
                  icon="fas fa-plus"
                  v-bind:disabled="!canCreateOrder(usage)"
                  v-bind:click-action="() => onClickCreateOrder(usage)"
                />
                <!-- If there's related orders, add them as buttons -->
                <template v-if="hasRelatedOrder(usage)">
                  <ActionSettingsWheelItemLabel
                    :label="SessionUser.objects.orders.meta.labels.multiple"
                    />
                  <ActionSettingsWheelItem
                    v-for="(order, orderIndex) in listRelatedOrders(usage)"
                    :key="orderIndex"
                    :label="`${SessionUser.functions.ucFirst(SessionUser.objects.orders.meta.labels.single)} #${order}`"
                    icon="fas fa-file-invoice"
                    v-bind:click-action="() => redirectDepartmentOrderPage(order)"
                  />
                </template>
              </template>
            </ActionSettingsWheelButton>
          </td>
        </tr>
        <template v-if="usage.WashItems && 1 === 2">
          <!-- Nested table for wash items -->
          <tr>
            <td colspan="100%">
              <table class="table is-fullwidth is-striped is-hoverable is-bordered">
                <thead>
                  <tr>
                    <th>Wash Item</th>
                    <th>Count</th>
                    <th>Price</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(item, itemIndex) in usage.WashItems" :key="itemIndex">
                    <td>{{ getProductName(item) }}</td>
                    <td>{{ item.Count }}</td>
                    <td>{{ item.PriceIncVat }}</td>
                  </tr>
                </tbody>
              </table>
            </td>
          </tr>
        </template>
      </template>
    </tbody>
  </table>
</template>

<style scoped>

</style>