// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <div>
    <a-button
      type="primary"
      @click="createVgpuProfile"
    >
      {{ $t('label.add.vgpu.profile') }}
    </a-button>
    <list-view
      :tabLoading="tabLoading"
      :columns="columns"
      :items="items"
      :columnKeys="columnKeys"
      :selectedColumns="selectedColumnKeys"
      ref="listview"
      @update-selected-columns="updateSelectedColumns"
      @refresh="this.fetchData"
    >
      <template #actionButtons="{ record }">
        <a-space>
          <!-- Edit Action -->
          <a-tooltip :title="$t('label.edit')">
            <a-button
              type="primary"
              size="small"
              shape="circle"
              @click="editVgpuProfile(record)"
            >
              <template #icon><edit-outlined /></template>
            </a-button>
          </a-tooltip>

          <!-- Delete Action -->
          <a-popconfirm
            :title="$t('message.confirm.delete.vgpu.profile')"
            @confirm="deleteVgpuProfile(record)"
            okText="Yes"
            cancelText="No"
          >
            <a-tooltip :title="$t('label.delete')">
              <a-button
                type="primary"
                danger
                size="small"
                shape="circle"
              >
                <template #icon><delete-outlined /></template>
              </a-button>
            </a-tooltip>
          </a-popconfirm>
        </a-space>
      </template>
    </list-view>

    <!-- Create/Update VGPU Profile Modal -->
    <a-modal
      :visible="showModal"
      :title="isEditing ? $t('label.update.vgpu.profile') : $t('label.add.vgpu.profile')"
      :closable="true"
      :maskClosable="false"
      :footer="null"
      @cancel="closeModal"
      centered
      width="450px"
    >
      <a-spin
        :spinning="actionLoading"
        v-ctrl-enter="handleSubmit"
      >
        <a-form
          ref="vgpuForm"
          :model="form"
          :rules="rules"
          layout="vertical"
          @finish="handleSubmit"
        >
          <a-form-item
            v-for="field in formFields"
            :key="field.key"
            :name="field.key"
            :ref="field.key"
            :label="field.label"
          >
            <!-- Input field -->
            <a-input
              v-if="field.type === 'input'"
              v-model:value="form[field.key]"
              :placeholder="field.placeholder"
              :v-focus="field.key === 'name'"
            />

            <!-- Number input field -->
            <a-input-number
              v-else-if="field.type === 'number'"
              style="width: 100%"
              v-model:value="form[field.key]"
              :min="field.min"
              :placeholder="field.placeholder"
            />
          </a-form-item>

          <div
            :span="24"
            class="action-button"
          >
            <a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
            <a-button
              type="primary"
              ref="submit"
              @click="handleSubmit"
            >{{ $t('label.ok') }}</a-button>
          </div>
        </a-form>
      </a-spin>
    </a-modal>
  </div>
</template>

<script>
import { reactive, toRaw } from 'vue'
import { getAPI, postAPI } from '@/api'
import { genericCompare } from '@/utils/sort.js'
import ListView from '@/components/view/ListView'
import { EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'

export default {
  name: 'VgpuProfilesTab',
  components: {
    ListView,
    EditOutlined,
    DeleteOutlined
  },
  props: {
    resource: {
      type: Object,
      required: true
    },
    loading: {
      type: Boolean,
      required: true
    }
  },
  data () {
    return {
      tabLoading: false,
      columnKeys: ['name', 'videoram', 'maxheads', 'resolution', 'maxvgpuperphysicalgpu'],
      selectedColumnKeys: [],
      columns: [],
      cols: [],
      items: [],
      showModal: false,
      isEditing: false,
      selectedVgpuProfile: null,
      actionLoading: false,
      form: {},
      rules: {},
      formFields: [],
      createApiParams: {},
      updateApiParams: {}
    }
  },
  computed: {
    isAdmin () {
      return this.$store.getters.userInfo.roletype === 'Admin'
    }
  },
  created () {
    this.fetchApiParams()
    this.selectedColumnKeys = this.columnKeys
    this.updateColumns()
    this.fetchData()
  },
  methods: {
    fetchApiParams () {
      this.createApiParams = this.$getApiParams('createVgpuProfile') || {}
      this.updateApiParams = this.$getApiParams('updateVgpuProfile') || {}
    },
    generateFormFields (isEdit = false) {
      const apiParams = isEdit ? this.updateApiParams : this.createApiParams
      const fields = []
      const fieldOrder = ['name', 'description', 'videoram', 'maxheads', 'maxresolutionx', 'maxresolutiony', 'maxvgpuperphysicalgpu']

      fieldOrder.forEach(paramName => {
        if (paramName === 'gpucardid' && !isEdit) return // Skip gpucardid for create as it's auto-populated

        const param = apiParams[paramName]
        if (!param && !isEdit) return // For create, only include params that exist in API

        const field = {
          key: paramName,
          label: this.$t(`label.${paramName}`),
          required: param?.required || (paramName === 'name' || paramName === 'maxvgpuperphysicalgpu'),
          placeholder: param?.description || this.$t(`label.${paramName}`),
          type: this.getFieldType(paramName, param)
        }

        fields.push(field)
      })

      this.formFields = fields
    },
    getFieldType (paramName, param) {
      const numberFields = ['maxvgpuperphysicalgpu']
      const selectFields = []

      if (numberFields.includes(paramName)) {
        return 'number'
      } else if (selectFields.includes(paramName)) {
        return 'select'
      } else {
        return 'input'
      }
    },
    initForm (isEdit = false, record = null) {
      const formData = {
        name: '',
        description: '',
        maxvgpuperphysicalgpu: 1
      }

      if (isEdit && record) {
        formData.name = record.name || ''
        formData.description = record.description || ''
        formData.maxvgpuperphysicalgpu = record.maxvgpuperphysicalgpu || 1
        formData.videoram = record.videoram || 0
        formData.maxheads = record.maxheads || 0
        formData.maxresolutionx = record.maxresolutionx || 0
        formData.maxresolutiony = record.maxresolutiony || 0
      }

      this.form = reactive(formData)

      const validationRules = {
        name: [{ required: true, message: this.$t('message.error.required.input') }],
        maxvgpuperphysicalgpu: [{ required: true, message: this.$t('message.error.required.input') }]
      }

      this.rules = reactive(validationRules)
    },
    createVgpuProfile () {
      this.isEditing = false
      this.selectedVgpuProfile = null
      this.generateFormFields(false)
      this.initForm(false)
      this.showModal = true
    },
    editVgpuProfile (record) {
      this.isEditing = true
      this.selectedVgpuProfile = record
      this.generateFormFields(true)
      this.initForm(true, record)
      this.showModal = true
    },
    closeModal () {
      this.showModal = false
      this.isEditing = false
      this.selectedVgpuProfile = null
      this.actionLoading = false
    },
    filterOption (input, option) {
      return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    handleSubmit (e) {
      if (e) {
        e.preventDefault()
      }
      if (this.actionLoading) return

      this.$refs.vgpuForm.validate().then(() => {
        this.actionLoading = true
        const formRaw = toRaw(this.form)

        if (this.isEditing) {
          this.updateVgpuProfile(formRaw)
        } else {
          this.createVgpuProfileSubmit(formRaw)
        }
      }).catch((error) => {
        this.$message.error(error)
      })
    },
    createVgpuProfileSubmit (formRaw) {
      const params = {
        name: formRaw.name,
        gpucardid: this.resource.id,
        maxvgpuperphysicalgpu: formRaw.maxvgpuperphysicalgpu
      }

      if (formRaw.description) {
        params.description = formRaw.description
      }

      postAPI('createVgpuProfile', params).then(response => {
        this.$message.success(this.$t('message.success.create.vgpu.profile'))
        this.closeModal()
        this.fetchData()
      }).catch(error => {
        console.error('Error creating vGPU profile:', error)
        this.$notifyError(error)
      }).finally(() => {
        this.actionLoading = false
      })
    },
    updateVgpuProfile (formRaw) {
      const params = {
        id: this.selectedVgpuProfile.id
      }

      // Add only fields that have values
      if (formRaw.name) {
        params.name = formRaw.name
      }
      if (formRaw.description) {
        params.description = formRaw.description
      }
      if (formRaw.maxvgpuperphysicalgpu) {
        params.maxvgpuperphysicalgpu = formRaw.maxvgpuperphysicalgpu
      }

      postAPI('updateVgpuProfile', params).then(() => {
        this.$message.success(this.$t('message.success.update.vgpu.profile'))
        this.closeModal()
        this.fetchData()
      }).catch(error => {
        console.error('Error updating vGPU profile:', error)
        this.$notifyError(error)
      }).finally(() => {
        this.actionLoading = false
      })
    },
    deleteVgpuProfile (record) {
      postAPI('deleteVgpuProfile', {
        id: record.id
      }).then(() => {
        this.$message.success(this.$t('message.success.delete.vgpu.profile'))
        this.fetchData()
      }).catch(error => {
        console.error('Error deleting vGPU profile:', error)
        this.$notifyError(error)
      })
    },
    fetchData () {
      this.fetchVgpuProfiles()
    },
    updateSelectedColumns (key) {
      if (this.selectedColumnKeys.includes(key)) {
        this.selectedColumnKeys = this.selectedColumnKeys.filter(x => x !== key)
      } else {
        this.selectedColumnKeys.push(key)
      }
      this.updateColumns()
    },
    updateColumns () {
      this.columns = []
      for (var columnKey of this.columnKeys) {
        if (!this.selectedColumnKeys.includes(columnKey)) continue
        this.columns.push({
          key: columnKey,
          title: columnKey === 'name' ? this.$t('label.vgpu.profile') : this.$t('label.' + String(columnKey).toLowerCase()),
          dataIndex: columnKey,
          sorter: (a, b) => { return genericCompare(a[columnKey] || '', b[columnKey] || '') }
        })
      }

      // Add actions column for admin users
      if (this.isAdmin) {
        this.columns.push({
          key: 'vgpuActions',
          title: this.$t('label.actions'),
          width: 120,
          fixed: 'right'
        })
      }

      if (this.columns.length > 0) {
        this.columns[this.columns.length - 1].customFilterDropdown = true
      }
    },
    fetchVgpuProfiles () {
      getAPI('listVgpuProfiles', {
        gpucardid: this.resource.id
      }).then(res => {
        this.items = res?.listvgpuprofilesresponse?.vgpuprofile || []
      })
    }
  }
}
</script>
