<script setup lang="ts">
import type { TablePaginationConfig } from 'antdv-next';

import { computed, ref, watch } from 'vue';

import { $t } from '@/locales';
import {
  Button,
  DatePicker,
  Input,
  Menu,
  message,
  Modal,
  Select,
  Switch,
  Table,
} from 'antdv-next';
import md5 from 'crypto-js/md5';
import dayjs, { Dayjs } from 'dayjs';
import localeData from 'dayjs/plugin/localeData';
import weekday from 'dayjs/plugin/weekday';

import {
  addProjectToUserApi,
  addUserApi,
  deleteUserFromApplicationApi,
  getAssociatedProjectsApi,
  getAvailableProjectsApi,
  updateUserApi,
} from '#/api';

interface Props {
  open: boolean;
  mode: 'add' | 'edit';
  userData?: any;
}

const props = defineProps<Props>();
const emit = defineEmits<{
  (e: 'save', data: any): void;
  (e: 'update:open', value: boolean): void;
}>();
dayjs.extend(weekday);
dayjs.extend(localeData);

const activeMenu = ref('basic');

const formData = ref({
  id: '',
  account: '',
  chineseName: '',
  englishName: '',
  cellPhone: '',
  emailAddress: '',
  gogs_email: '',
  expiredTime: null as Dayjs | null,
  isActive: true,
  password: '',
});

const relatedProjects = ref<any[]>([]);

const projectSearchKeyword = ref('');
const projectModalOpen = ref(false);
const selectedProjects = ref<any[]>([]);

const menuItems = computed(() => [
  {
    key: 'basic',
    label: $t('deliveryPartners.modal.basic'),
    title: $t('deliveryPartners.modal.basic'),
  },
  {
    key: 'projects',
    label: $t('deliveryPartners.modal.projects'),
    title: $t('deliveryPartners.modal.projects'),
  },
]);

const allProjects = ref<any[]>([]);
const projectPagination = ref({
  currentPage: 1,
  pageSize: 10,
  total: 0,
});

const roleOptions = [
  { value: '普通人员', label: '普通人员' },
  { value: '兼职人员', label: '兼职人员' },
  { value: '内部人员', label: '内部人员' },
  { value: '管理员', label: '管理员' },
];

async function fetchAssociatedProjects() {
  try {
    const result = await getAssociatedProjectsApi(formData.value.id);
    if (result?.result?.model) {
      relatedProjects.value = result.result.model;
    }
  } catch {}
}

async function fetchAvailableProjects() {
  try {
    const result = await getAvailableProjectsApi({
      currentPage: projectPagination.value.currentPage,
      pageSize: projectPagination.value.pageSize,
      orderByProperty: 'name',
      Ascending: true,
      filters: [
        {
          name: 'name',
          value: projectSearchKeyword.value,
        },
      ],
    });
    if (result?.result?.model) {
      result.result.model.forEach((item: any) => {
        item.roleTypes = '普通人员';
      });
      allProjects.value = result.result.model;
      projectPagination.value.total = result.result.totalCount;
    }
  } catch {}
}

watch(
  () => props.open,
  (val) => {
    if (val && props.mode === 'edit' && props.userData) {
      // 逐个属性赋值，避免类型错误
      formData.value.id = props.userData.id || '';
      formData.value.account = props.userData.account || '';
      formData.value.chineseName = props.userData.chineseName || '';
      formData.value.englishName = props.userData.englishName || '';
      formData.value.cellPhone = props.userData.cellPhone || '';
      formData.value.emailAddress = props.userData.emailAddress || '';
      formData.value.gogs_email = props.userData.gogs_email || '';
      formData.value.isActive = props.userData.isActive;
      try {
        formData.value.expiredTime = props.userData.expiredTime
          ? dayjs(props.userData.expiredTime)
          : null;
      } catch {
        formData.value.expiredTime = null;
      }
      fetchAssociatedProjects();
      fetchAvailableProjects();
    }
    if (val) {
      if (props.mode === 'add') {
        resetFormData();
      }
      activeMenu.value = 'basic';
    }
  },
);

const isOpen = computed({
  get: () => props.open,
  set: (val) => emit('update:open', val),
});

function handleMenuClick({
  key,
}: {
  domEvent: Event;
  item: any;
  key: string;
  keyPath: string[];
}) {
  activeMenu.value = key;
}

async function handleSave() {
  const data = {
    id: formData.value.id,
    langNameList: [
      {
        name: 'zh-CN',
        value: formData.value.chineseName,
      },
      {
        name: 'en',
        value: formData.value.englishName,
      },
    ],
    expiredTime: formData.value.expiredTime
      ? formData.value.expiredTime.format('YYYY-MM-DD')
      : '',
    langName: null,
    account: formData.value.account,
    password:
      props.mode === 'add' ? md5(formData.value.password).toString() : '',
    cellPhone: formData.value.cellPhone,
    emailAddress: formData.value.emailAddress,
    gogs_email: formData.value.gogs_email,
    isActive: formData.value.isActive,
  };
  try {
    const result = formData.value.id
      ? await updateUserApi(data)
      : await addUserApi(data);
    if (result?.isSuccess) {
      emit('save', data);
      isOpen.value = false;
      message.success($t('deliveryPartners.saveSuccess'));
    }
  } catch {}
}

function handleCancel() {
  isOpen.value = false;
}

function handleAddProject() {
  projectModalOpen.value = true;
  projectSearchKeyword.value = '';
  selectedProjects.value = [];
  fetchAvailableProjects();
}

function handleProjectSearch() {
  projectPagination.value.currentPage = 1;
  fetchAvailableProjects();
}

function handleProjectPageChange(pagination: TablePaginationConfig) {
  if (pagination.current && pagination.pageSize) {
    projectPagination.value.currentPage = pagination.current;
    projectPagination.value.pageSize = pagination.pageSize;
    fetchAvailableProjects();
  }
}

async function handleProjectSelect(project: any) {
  if (!project.expiredTime) {
    message.error($t('deliveryPartners.enterExpiredTime'));
    return;
  }
  try {
    const result = await addProjectToUserApi(
      [project.id],
      formData.value.id,
      project.roleTypes,
      project.expiredTime ? project.expiredTime.format('YYYY-MM-DD') : '',
    );
    if (result?.isSuccess) {
      message.success($t('deliveryPartners.addProjectSuccess'));
      fetchAssociatedProjects();
      projectModalOpen.value = false;
    }
  } catch {}
}

async function handleProjectDelete(project: any) {
  Modal.confirm({
    title: $t('btn.delete'),
    content: $t('deliveryPartners.modal.deleteProjectConfirm'),
    okText: $t('btn.yes'),
    okType: 'danger',
    cancelText: $t('btn.no'),
    type: 'warning',
    onOk: async () => {
      try {
        const result = await deleteUserFromApplicationApi(formData.value.id, [
          project.id,
        ]);
        if (result?.isSuccess) {
          message.success($t('deliveryPartners.deleteProjectSuccess'));
          fetchAssociatedProjects();
        }
      } catch {}
    },
    onCancel: () => {},
  });
}

function resetFormData() {
  formData.value = {
    id: '',
    account: '',
    chineseName: '',
    englishName: '',
    cellPhone: '',
    emailAddress: '',
    gogs_email: '',
    expiredTime: null,
    isActive: true,
    password: '',
  };

  relatedProjects.value = [];
}
</script>

<template>
  <Modal
    v-model:open="isOpen"
    :footer="null"
    :title="
      props.mode === 'add'
        ? $t('deliveryPartners.modal.addTitle')
        : $t('deliveryPartners.modal.editTitle')
    "
    width="1200px"
  >
    <div class="flex h-[600px]">
      <div
        v-if="props.mode !== 'add'"
        class="w-[200px] border-r border-gray-200"
      >
        <Menu
          :items="menuItems"
          :selected-keys="[activeMenu]"
          mode="vertical"
          @click="handleMenuClick"
          @update:selected-keys="(keys) => (activeMenu = keys[0] ?? 'basic')"
        />
      </div>

      <div class="flex-1 overflow-y-auto p-6">
        <div v-show="activeMenu === 'basic'" class="space-y-4">
          <div class="grid grid-cols-2 gap-4">
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.chineseName')
              }}</label>
              <Input
                v-model:value="formData.chineseName"
                :placeholder="$t('deliveryPartners.modal.enterChineseName')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.englishName')
              }}</label>
              <Input
                v-model:value="formData.englishName"
                :placeholder="$t('deliveryPartners.modal.enterEnglishName')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.account')
              }}</label>
              <Input
                v-model:value="formData.account"
                :disabled="props.mode === 'edit'"
                :placeholder="$t('deliveryPartners.modal.enterAccount')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.cellPhone')
              }}</label>
              <Input
                v-model:value="formData.cellPhone"
                :placeholder="$t('deliveryPartners.modal.enterCellPhone')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.emailAddress')
              }}</label>
              <Input
                v-model:value="formData.emailAddress"
                :placeholder="$t('deliveryPartners.modal.enterEmailAddress')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.gogsEmail')
              }}</label>
              <Input
                v-model:value="formData.gogs_email"
                :placeholder="$t('deliveryPartners.modal.enterGogsEmail')"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.expiredTime')
              }}</label>
              <DatePicker
                v-model:value="formData.expiredTime"
                :placeholder="$t('deliveryPartners.modal.selectExpiredTime')"
                format="YYYY-MM-DD"
                style="width: 100%"
              />
            </div>
            <div class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.isActive')
              }}</label>
              <Switch v-model:checked="formData.isActive" class="w-[40px]" />
            </div>
            <div v-if="props.mode === 'add'" class="flex flex-col gap-2">
              <label class="text-sm font-medium">{{
                $t('deliveryPartners.modal.password')
              }}</label>
              <Input
                v-model:value="formData.password"
                :placeholder="$t('deliveryPartners.modal.enterPassword')"
                type="password"
              />
            </div>
          </div>
        </div>

        <div v-show="activeMenu === 'projects'" class="space-y-4">
          <div class="mb-4 flex items-center justify-between">
            <Button type="primary" @click="handleAddProject">
              {{ $t('deliveryPartners.modal.add') }}
              {{ $t('deliveryPartners.modal.projects') }}
            </Button>
          </div>

          <Table
            :columns="[
              {
                title: $t('deliveryPartners.modal.projectName'),
                dataIndex: 'name',
                key: 'name',
              },
              {
                title: $t('deliveryPartners.modal.projectCode'),
                dataIndex: 'code',
                key: 'code',
              },
              {
                title: $t('deliveryPartners.modal.role'),
                dataIndex: 'roleTypes',
                key: 'roleTypes',
              },
              {
                title: $t('deliveryPartners.modal.expiredTime'),
                dataIndex: 'expiredTime',
                key: 'expiredTime',
              },
              {
                title: $t('deliveryPartners.modal.action'),
                key: 'action',
                width: 100,
              },
            ]"
            :data-source="relatedProjects"
            :pagination="false"
            :scroll="{ y: 460 }"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'action'">
                <Button
                  danger
                  size="small"
                  @click="handleProjectDelete(record)"
                >
                  {{ $t('deliveryPartners.modal.delete') }}
                </Button>
              </template>
            </template>
          </Table>
        </div>
      </div>
    </div>

    <div
      v-if="activeMenu === 'basic'"
      class="flex justify-end gap-2 border-t pt-4"
    >
      <Button @click="handleCancel">
        {{ $t('deliveryPartners.modal.cancel') }}
      </Button>
      <Button type="primary" @click="handleSave">
        {{ $t('deliveryPartners.modal.save') }}
      </Button>
    </div>

    <Modal
      v-model:open="projectModalOpen"
      :footer="null"
      :title="$t('deliveryPartners.modal.addProjectTitle')"
      width="760"
    >
      <div class="space-y-4">
        <Input
          v-model:value="projectSearchKeyword"
          :placeholder="$t('deliveryPartners.modal.searchProject')"
          @change="handleProjectSearch"
        />
        <Table
          :columns="[
            {
              title: $t('deliveryPartners.modal.projectName'),
              dataIndex: 'name',
              key: 'name',
              ellipsis: true,
              width: 120,
            },
            {
              title: $t('deliveryPartners.modal.projectCode'),
              dataIndex: 'code',
              key: 'code',
              ellipsis: true,
              width: 120,
            },
            {
              title: $t('deliveryPartners.modal.role'),
              key: 'roleTypes',
              width: 150,
            },
            {
              title: $t('deliveryPartners.modal.expiredTime'),
              key: 'expiredTime',
              width: 150,
            },
            {
              title: $t('deliveryPartners.modal.action'),
              key: 'action',
            },
          ]"
          :data-source="allProjects"
          :pagination="{
            current: projectPagination.currentPage,
            pageSize: projectPagination.pageSize,
            total: projectPagination.total,
            showSizeChanger: true,
            showTotal: (total: number) =>
              $t('deliveryPartners.modal.totalProjects', { total }),
          }"
          :scroll="{ y: 460 }"
          class="project-table"
          @change="handleProjectPageChange"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'roleTypes'">
              <Select
                v-model:value="record.roleTypes"
                :options="roleOptions"
                style="width: 120px"
              />
            </template>
            <template v-if="column.key === 'expiredTime'">
              <DatePicker
                v-model:value="record.expiredTime"
                format="YYYY-MM-DD"
                style="width: 120px"
              />
            </template>
            <template v-if="column.key === 'action'">
              <Button
                size="small"
                type="primary"
                @click="handleProjectSelect(record)"
              >
                {{ $t('deliveryPartners.modal.add') }}
              </Button>
            </template>
          </template>
        </Table>
      </div>
    </Modal>
  </Modal>
</template>

<style lang="scss">
.ant-menu-light .ant-menu-item-selected,
.ant-menu-light > .ant-menu .ant-menu-item-selected {
  background-color: #f4f2f2;

  .ant-menu-title-content {
    color: #462424;
  }
}

.ant-table-wrapper .ant-table-tbody > tr > th,
.ant-table-wrapper .ant-table-tbody > tr > td {
  padding: 8px 16px;
}

.ant-table-wrapper .ant-table-thead > tr > th,
.ant-table-wrapper .ant-table-thead > tr > td {
  padding: 8px 16px;
}
</style>
