import type { List, Tree } from '@/model';
import type { RoleModel, RoleQuery, TagModel, TagQuery, UserModel, UserQuery, OrganizationModel, OrganizationQuery, InstitutionModel, InstitutionQuery } from '@/model/system.model';
import { fromTag } from '@/model/system.model';

import request from '@/request/alova';

export function branchMethod(one?: number, two?: number, three?: number) {
  return request.Get<Tree<{ id: string; label: string }>>(
    `/system/user/deptTree${one !== undefined && one !== null ? '/' + one : ''}${two !== undefined && two !== null ? '/' + two : ''}${three !== undefined && three !== null ? '/' + three : ''}`
  );
}

export function usersMethod(page: number, size: number, query?: UserQuery) {
  return request.Get<List<RoleModel>>(`/system/user/list`, {
    hitSource: /user$/,
    params: { pageNum: page, pageSize: size, ...query },
  });
}

export function userMethod(data: Partial<UserModel>) {
  return request.Get<UserModel, any>(`/system/user/${data.userId}`, {
    hitSource: 'edit-user',
    transform(data) {
      let roleIds = data?.roleIds ?? [];
      if (!roleIds.length) roleIds = data?.roles?.map?.((t: any) => t.roleId);
      return { ...data, roleIds };
    },
  });
}

export function editUserMethod(data: Partial<UserModel>) {
  return data.userId ? request.Put(`/system/user`, data, { name: 'edit-user' }) : request.Post(`/system/user`, data, { name: 'edit-user' });
}

export function deleteUserMethod(data: Partial<UserModel>) {
  return request.Delete(`/system/user/${data.userId}`, { name: 'delete-user' });
}

export function updateUserPasswordMethod(data: Record<string, any>, update = false) {
  if (update) {
    const params = { oldPassword: data.old, newPassword: data.password };
    return request.Put(`/system/user/profile/updatePwd`, {}, { params });
  }
  return request.Put(`/system/user/resetPwd`, data);
}

export function rolesAllMethod() {
  return request.Get<List<RoleModel>>(`/system/role/optionselect`);
}

export function rolesMethod(page: number, size: number, query?: RoleQuery) {
  return request.Get<List<RoleModel>>(`/system/role/list`, {
    hitSource: /role$/,
    params: { pageNum: page, pageSize: size, ...query },
  });
}

export function roleMethod(data: Partial<RoleModel>) {
  return request.Get<RoleModel>(`/system/role/${data.roleId}`, {
    hitSource: 'edit-role',
  });
}

export function editRoleMethod(data: Partial<RoleModel>) {
  return data.roleId ? request.Put(`/system/role`, data, { name: 'edit-role' }) : request.Post(`/system/role`, data, { name: 'edit-role' });
}

export function deleteRoleMethod(data: Partial<RoleModel>) {
  return request.Delete(`/system/role/${data.roleId}`, { name: 'delete-role' });
}

export function updateRoleStatusMethod(data: Partial<RoleModel>) {
  return request.Put(`/system/role/changeStatus`, { roleId: data.roleId, status: data.status }, { name: 'update-role' });
}

type RoleMenu = { id: string; label: string; children?: RoleMenu[] };

export function getRoleMenusMethod(data?: Partial<RoleModel>) {
  return data?.roleId
    ? request.Get<{ selected: string[]; menus: RoleMenu[] }, { menus: RoleMenu[]; checkedKeys: string[] }>(`/system/menu/roleMenuTreeselect/${data.roleId}`, {
        hitSource: 'edit-role',
        meta: { unconvert: true },
        transform(data) {
          const flat = (menus?: RoleMenu[]): RoleMenu[] => (Array.isArray(menus) ? menus.flatMap((item) => [item, ...flat(item.children)]) : []);
          const menus = flat(data.menus);
          const selected = Array.isArray(data.checkedKeys) ? data.checkedKeys.filter((key) => !menus.find((menu) => menu.id === key)?.children) : [];
          return { menus: data.menus, selected };
        },
      })
    : request.Get<{ selected: string[]; menus: RoleMenu[] }, RoleMenu[]>(`/system/menu/treeselect`, {
        transform(data) {
          return { menus: data, selected: [] };
        },
      });
}

export function tagsMethod(page: number, size: number, query?: TagQuery & { type?: Required<TagQuery>['types'][number] }) {
  if (Array.isArray(query?.parentIds)) query.parentId = query.parentIds.join(',');
  else if (query?.parentIds) query.parentId = query?.parentIds as string;
  if (query?.types?.length === 1) query.type = query.types[0];
  return request.Post<List<TagModel>, List<any>>(`/fdhb-pc/tagManage/pageTag`, query ?? {}, {
    hitSource: /tag$/,
    params: { pageNum: page, pageSize: size },
    transform({ total, data }) {
      return { total, data: data.map(fromTag) };
    },
  });
}

export function tagsSearchMethod(query?: TagQuery) {
  return request.Post<List<TagModel>, TagModel[]>(`/fdhb-pc/tagManage/selectTag`, query ?? {}, {
    hitSource: /tag$/,
    transform(data) {
      return { total: data.length, data: data.map(fromTag) };
    },
  });
}

export function tagMethod(data: Partial<TagModel>) {
  return request.Get<TagModel>(`/fdhb-pc/tagManage/getTag`, {
    hitSource: 'edit-tag',
    params: { tagId: data.id },
  });
}

export function tagEditMethod(data: Partial<TagModel>) {
  return data.id
    ? request.Post(`/fdhb-pc/tagManage/updateTag`, { ...data, tagId: data.id }, { name: 'edit-tag' })
    : request.Post(`/fdhb-pc/tagManage/addTag`, data, { name: 'edit-tag' });
}

export function tagDeleteMethod(data: Partial<TagModel>) {
  return request.Get(`/fdhb-pc/tagManage/deleteTag`, {
    name: 'delete-tag',
    params: { tagId: data.id },
    cacheFor: null,
  });
}

export function tagUpdateStatusMethod(data: Partial<TagModel>) {
  return request.Get(`/fdhb-pc/tagManage/updateStatus`, {
    name: 'update-tag',
    params: { tagId: data.id, status: data.status },
    cacheFor: null,
  });
}

// 添加机构
export function addInstitutionMethod(data: { name: string; parentId: string; description?: string }) {
  return request.Post<{ id: string; name: string }>(`/system/dept/add`, data, {
    name: 'add-institution',
    cacheFor: null,
  });
}
// 获取组织管理列表
export function organizationMethod(page: number, size: number, query?: OrganizationQuery) {
  return request.Post<List<OrganizationModel>, List<any>>(`/fdhb-pc/orgManage/pageOrg`, query ?? {}, {
    hitSource: /organization$/,
    params: { pageNum: page, pageSize: size, ...query },
  });
}
// 新增/修改组织
export function addOrganizationMethod(data: Partial<OrganizationModel>) {
  return data.id
    ? request.Post(`/fdhb-pc/orgManage/updateOrg`, data, { name: 'edit-organization' })
    : request.Post(`/fdhb-pc/orgManage/addOrg`, data, { name: 'add-organization' });
}
// 删除组织
export function deleteOrganizationMethod(data: Partial<OrganizationModel>) {
  return request.Post(`/fdhb-pc/orgManage/deleteOrg/${data.id}`, {
    name: 'delete-organization',
  });
}
// 患者归属设置
export function setPatientBelongMethod(data: Partial<OrganizationModel>) {
  return request.Post(`/fdhb-pc/orgManage/defaultIns/${data.id}/${data.insId}`, { name: 'set-patient-belong' });
}

// 获取机构列表
export function institutionMethod(page: number, size: number, query?: InstitutionQuery) {
  return request.Post<List<InstitutionModel>, List<any>>(`/fdhb-pc/insManage/pageIns`, query ?? {}, {
    hitSource: /institution$/,
    params: { pageNum: page, pageSize: size, ...query },
  });
}
// 新增/删除机构
export function editInstitutionMethod(data: Partial<InstitutionModel>) {
  return data.id ? request.Post(`/fdhb-pc/insManage/updateIns`, data, { name: 'edit-institution' }) : request.Post(`/fdhb-pc/insManage/addIns`, data, { name: 'add-institution' });
}
// 删除机构
export function deleteInstitutionMethod(data: Partial<InstitutionModel>) {
  return request.Post(`/fdhb-pc/insManage/deleteIns/${data.id}`, { name: 'delete-institution' });
}