export default defineNuxtPlugin((nuxtApp) => {
  const module = "application";
  const mode = "dev";
  const paths = [
    { name: "dev", url: "https://erpapi.bigdatatech.vn/" },
    { name: "local", url: "http://localhost:8000/" },
    { name: "prod", url: "https://erpapi.bigdatatech.vn/" },
  ];
  const path = paths.find((v) => v.name === mode).url;
  const apis = [
    { name: "sendemail", url: "send-email/" },
    { name: "deleteentry", url: "delete-entry/" },
    { name: "emailpreview", url: "email-preview/" },
    { name: "workflow", url: "workflow/execute/" },
    { name: "accountentry", url: "account-entry/", params: {} },
    { name: "accountmultientry", url: "account-multi-entry/", params: {} },
    {
      name: "entryfile",
      url: "data/Entry_File/",
      url_detail: "data-detail/Entry_File/",
      params: {
        values: "id,file__file,file__name,file__caption,file,file__user__fullname,create_time",
      },
    },
    {
      name: "importsetting",
      url: "data/Import_Setting/",
      url_detail: "data-detail/Import_Setting/",
      params: {},
    },
    { name: "modelfields", url: "model-fields/", params: {} },
    { name: "readexcel", url: "read-excel/", params: {} },
    { name: "findkey", url: "find-key/", params: {} },
    {
      name: "dealerrights",
      url: "data/Biz_Rights/",
      url_detail: "data-detail/Biz_Rights/",
      params: { sort: "-id" },
    },
    {
      name: "individual",
      url: "data/Individual/",
      url_detail: "data-detail/Individual/",
      params: {
        sort: "-id",
        values: "id,customer,dob,sex,sex__name,sex__en,zalo,facebook,company,company__fullname,create_time,update_time",
      },
    },
    {
      name: "transactiondiscount",
      url: "data/Transaction_Discount/",
      url_detail: "data-detail/Transaction_Discount/",
      params: {
        values:
          "id,transaction,discount,discount__code,discount__name,type,type__code,type__name,value,create_time,update_time",
      },
    },
    {
      name: "organization",
      url: "data/Organization/",
      url_detail: "data-detail/Organization/",
      params: {
        sort: "-id",
        values: "id,customer,shortname,established_date,website,type,type__name,create_time,update_time",
      },
    },
    {
      name: "co_op",
      url: "data/Co_Ownership/",
      url_detail: "data-detail/Co_Ownership/",
      params: {
        values: "id,transaction,people,people__code,people__fullname,people__phone,people__legal_code",
      },
    },
    {
      name: "companytype",
      url: "data/Company_Type/",
      url_detail: "data-detail/Company_Type/",
      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "cart",
      url: "data/Cart/",
      url_detail: "data-detail/Cart/",
      commit: "cart",
      params: {
        sort: "id",
        values: "id,code,name,dealer,dealer__code,dealer__name,create_time",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["code", "name"],
          },
        },
        summary: "annotate",
      },
    },
    {
      name: "payment_schedule",
      url: "data/Payment_Schedule/",
      url_detail: "data-detail/Payment_Schedule/",
      params: {
        sort: "-id",
        values:
          "batch_date,amount_remain,penalty_remain,penalty_paid,penalty_amount,penalty_reduce,ovd_days,remain_amount,paid_amount,txn_detail__transaction__product__trade_code,txn_detail__status,txn_detail__transaction__product__code,txn_detail__phase__name,txn_detail,id,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__code,txn_detail__transaction__customer__legal_code,status__name,type__name,code,from_date,txn_detail__transaction__policy__code,to_date,amount,cycle,cycle_days,txn_detail__transaction,type,status,updater,entry,detail,txn_detail__transaction__code,txn_detail__code",
      },
    },
    {
      name: "people",
      url: "data/People/",
      url_detail: "data-detail/People/",
      params: {
        sort: "-id",
        values:
          "id,issued_place,issued_place__code,issued_place__name,contact_address,address,country__name,company__fullname,legal_code,company,country,email,creator,code,fullname,dob,sex,legal_code,sex__name,phone,issued_date,legal_type,legal_type__name,address,note,updater,updater__fullname,create_time,update_time",
        distinct_values: {
          label: { type: "Concat", field: ["code", "fullname", "phone"] },
          order: { type: "RowNumber" },
        },
        summary: "annotate",
      },
    },
    {
      name: "productnote",
      url: "data/Product_Note/",
      url_detail: "data-detail/Product_Note/",
      commit: "productnote",
      params: {
        sort: "id",
        values:
          "id,detail,user,user__username,user__fullname,create_time,update_time,ref,ref__cart__dealer,ref__trade_code",
      },
    },
    {
      name: "customernote",
      url: "data/Customer_Note/",
      url_detail: "data-detail/Customer_Note/",
      params: {
        values: "id,ref,detail,user,create_time,update_time",
      },
    },
    {
      name: "entrytype",
      url: "data/Entry_Type/",
      url_detail: "data-detail/Entry_Type/",
      params: {},
    },
    {
      name: "entrycategory",
      url: "data/Entry_Category/",
      url_detail: "data-detail/Entry_Category/",
      params: {},
    },
    {
      name: "accounttype",
      url: "data/Account_Type/",
      url_detail: "data-detail/Account_Type/",
      params: { sort: "id" },
    },
    {
      name: "internalaccount",
      url: "data/Internal_Account/",
      url_detail: "data-detail/Internal_Account/",
      params: {
        sort: "branch,currency,type",
        values:
          "id,currency,currency__code,currency__name,code,balance,create_time,update_time,type,type__code,type__name,branch,branch__code,branch__name",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["branch__name", "code", "type__name"],
          },
        },
        summary: "annotate",
      },
    },
    {
      name: "currency",
      url: "data/Currency/",
      url_detail: "data-detail/Currency/",
      params: {},
    },
    {
      name: "approvestatus",
      url: "data/Approve_Status/",
      url_detail: "data-detail/Approve_Status/",
      params: {},
    },
    {
      name: "bizrights",
      url: "data/Biz_Rights/",
      url_detail: "data-detail/Biz_Rights/",
      params: { sort: "-id" },
    },
    {
      name: "feetype",
      url: "data/Fee_Type/",
      url_detail: "data-detail/Fee_Type/",
      params: {
        sort: "id",
        values: "id,index,code,name,type,value,type__code,type__name,method,method__code,method__name,create_time",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["name", "method__name", "type__name", "value"],
          },
        },
        summary: "annotate",
      },
    },
    {
      name: "dealersetting",
      url: "data/Biz_Setting/",
      url_detail: "data-detail/Biz_Setting/",
      params: { sort: "index" },
    },
    {
      name: "documentaudit",
      url: "data/Document_Audit/",
      url_detail: "data-detail/Document_Audit/",
      params: { sort: "index" },
    },
    {
      name: "documenttype",
      url: "data/Document_Type/",
      url_detail: "data-detail/Document_Type/",
      params: { sort: "index" },
    },
    {
      name: "getcodeCustomer",
      url: "increment/Customer/KH/",

      params: {},
    },
    {
      name: "getcodepeople",
      url: "increment/People/RE/",

      params: {},
    },
    {
      name: "getcodecompany",
      url: "increment/Company/CP/",

      params: {},
    },
    {
      name: "country",
      url: "data/Country/",
      commit: "country",
      params: {
        sort: "id",
        values: "id,code,name,en,create_time",
      },
    },
    {
      name: "status",
      url: "data/Approve_Status/",

      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "image",
      url: "data/Image/",
      url_detail: "data-detail/Image/",
      params: {},
    },
    {
      name: "file",
      url: "data/File/",
      url_detail: "data-detail/File/",
      params: {},
    },
    {
      name: "filetype",
      url: "data/File_Type/",
      url_detail: "data-detail/File_Type/",
      params: {},
    },
    {
      name: "news",
      commit: "updateNews",
      url: "data/News/",
      url_detail: "data-detail/News/",
      params: { values: "id,title,subtitle,create_time" },
    },
    {
      name: "category",
      commit: "updateCategory",
      url: "data/Category/",
      url_detail: "data-detail/Category/",
      params: {},
    },
    {
      name: "contract",
      url: "data/Contract/",
      url_detail: "data-detail/Contract/",
      params: {
        sort: "-id",
      },
    },
    {
      name: "contractstatus",
      url: "data/Contract_Status/",
      url_detail: "data-detail/Contract_Status/",
      params: {},
    },
    {
      name: "token",
      url: "data/Token/",
      url_detail: "data-detail/Token/",
      params: {
        values:
          "id,token,browser,browser_version,ip,os,platform,expiry,create_time,update_time,user,user__fullname,user__username",
        sort: "-id",
      },
    },
    { name: "authtoken", url: "auth-token/", params: {} },
    {
      name: "notification",
      commit: "updateNotification",
      url: "data/Notify/",
      url_detail: "data-detail/Notify/",
      params: {
        values:
          "id,title,content,image,link,task_log,user,user__username,user__fullname,event,seen,create_time,event__code,event__name,update_time",
      },
    },
    {
      name: "common",
      commit: "common",
      url: "data/Common/",
      url_detail: "data-detail/Common/",
      params: { sort: "index" },
    },
    { name: "upload", url: "upload/", params: {} },
    {
      name: "paymentstatus",
      url: "data/Payment_Status/",
      url_detail: "data-detail/Payment_Status/",
      params: {
        values: "id,code,name,en,index,create_time",
      },
    },
    {
      name: "paymenttype",
      url: "data/Payment_Type/",
      url_detail: "data-detail/Payment_Type/",
      params: {
        values: "id,code,name,en,index,create_time",
      },
    },
    {
      name: "paymentmethod",
      url: "data/Payment_Method/",
      url_detail: "data-detail/Payment_Method/",
      params: {},
    },
    {
      name: "salepolicy",
      url: "data/Sale_Policy/",
      url_detail: "data-detail/Sale_Policy/",
      params: {
        values:
          "id,code,name,deposit,method,method__code,method__name,create_time,enable,contract_allocation_percentage,create_time,update_time,index",
        sort: "index",
      },
    },
    {
      name: "paymentplan",
      url: "data/Payment_Plan/",
      url_detail: "data-detail/Payment_Plan/",
      params: {
        values:
          "policy__enable,id,policy,policy__code,policy__name,cycle,value,type,days,payment_note,due_note,create_time,update_time",
        sort: "cycle",
      },
    },
    {
      name: "request",
      url: "data/Request/",
      url_detail: "data-detail/Request/",
      params: {},
    },
    {
      name: "register",
      url: "data/Register/",
      url_detail: "data-detail/Register/",
      params: {},
    },
    { name: "sendemail", url: "send-email/", path: "etl", params: {} },
    { name: "sendemailnow", url: "send-email-now/", path: "etl", params: {} },
    {
      name: "usersession",
      url: "data/User_Session/",
      url_detail: "data-detail/User_Session/",
      params: {},
    },
    {
      name: "userlog",
      url: "data/User_Log/",
      url_detail: "data-detail/User_Log/",
      params: {},
    },
    {
      name: "usersetting",
      url: "data/User_Setting/",
      url_detail: "data-detail/User_Setting/",
      params: {},
    },
    { name: "account-entry", url: "/account-entry/", params: {} },
    {
      name: "valuetype",
      url: "data/Value_Type/",
      url_detail: "data-detail/Value_Type/",
      params: {
        values: "id,code,name,en,index,create_time",
        sort: "index",
      },
    },
    {
      name: "bizsetting",
      commit: "bizsetting",
      url: "data/Biz_Setting/",
      url_detail: "data-detail/Biz_Setting/",
      params: {},
    },
    {
      name: "discounttype",
      commit: "discounttype",
      url: "data/Discount_Type/",
      url_detail: "data-detail/Discount_Type/",
      params: {
        values: "id,code,name,value,type,type__name,method,method__name",
        distinct_values: {
          label: { type: "Concat", field: ["code", "name", "type__name"] },
        },
        summary: "annotate",
      },
    },
    {
      name: "customer",
      url: "data/Customer/",
      url_detail: "data-detail/Customer/",
      params: {
        values:
          "id,update_time,creator,creator__fullname,country,country__name,country__en,issued_date,issued_place,issued_place__name,code,email,fullname,legal_code,phone,legal_type,legal_type__name,address,contact_address,note,type,type__name,updater,updater__fullname,create_time,update_time",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["code", "fullname", "phone", "legal_code"],
          },
          order: { type: "RowNumber" },
          image_count: {
            type: "Count",
            field: "id",
            subquery: { model: "Customer_File", column: "ref" },
          },
          count_note: {
            type: "Count",
            field: "id",
            subquery: { model: "Customer_Note", column: "ref" },
          },
          count_product: {
            type: "Count",
            field: "id",
            subquery: {
              model: "Product_Booked",
              column: "transaction__customer",
            },
          },
          sum_product: {
            type: "Sum",
            field: "transaction__sale_price",
            subquery: {
              model: "Product_Booked",
              column: "transaction__customer",
            },
          },
          sum_receiver: {
            type: "Sum",
            field: "transaction__amount_received",
            subquery: {
              model: "Product_Booked",
              column: "transaction__customer",
            },
          },
          sum_remain: {
            type: "Sum",
            field: "transaction__amount_remain",
            subquery: {
              model: "Product_Booked",
              column: "transaction__customer",
            },
          },
        },
        summary: "annotate",
        filter: { deleted: 0 },
        sort: "-id",
      },
    },
    {
      name: "transaction",
      commit: "transaction",
      url: "data/Transaction/",
      url_detail: "data-detail/Transaction/",
      params: {
        sort: "-date",
        values:
          "date,txncurrent__detail,txncurrent__detail__status,customer__type,txncurrent,txncurrent__detail__amount,txncurrent__detail__amount_remaining,txncurrent__detail__status__name,product__zone_type__name,product__trade_code,product__cart__dealer,customer__legal_code,customer__legal_type__name,payment_plan,id,code,customer,customer__code,customer__fullname,customer__phone,product,phase,phase__name,phase__code,policy,policy__code,policy__name,origin_price,discount_amount,sale_price,deposit_amount,deposit_received,deposit_remaining,amount_received,amount_remain,create_time,update_time",
      },
    },
    {
      name: "transactionphase",
      url: "data/Transaction_Phase/",
      url_detail: "data-detail/Transaction_Phase/",
      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "phasedoctype",
      url: "data/Phase_Doctype/",
      url_detail: "data-detail/Phase_Doctype/",
      params: {
        values: "id,phase,doctype,doctype__code,doctype__name",
        sort: "doctype__index",
      },
    },
    {
      name: "transactiontype",
      url: "data/Transaction_Type/",
      url_detail: "data-detail/Transaction_Type/",
      params: {
        values: "id,code,name,detail,create_time",
      },
    },
    {
      name: "reservation",
      commit: "reservation",
      url: "data/Transaction_Detail/",
      url_detail: "data-detail/Transaction_Detail/",
      params: {
        values:
          "id,code,date,amount,amount_received,amount_remaining,phase,due_date,transaction,creator,status,approver,approve_time,create_time,update_time",
      },
    },
    {
      name: "transactionfile",
      commit: "transactionfile",
      url: "data/Transaction_File/",
      url_detail: "data-detail/Transaction_File/",
      params: {
        values: "id,txn_detail,file,file__name,file__size,file__file,create_time,file__doc_type",
      },
    },
    {
      name: "productbooked",
      commit: "productbooked",
      url: "data/Product_Booked/",
      url_detail: "data-detail/Product_Booked/",
      params: {},
    },
    {
      name: "product",
      commit: "product",
      url: "data/Product/",
      url_detail: "data-detail/Product/",
      params: {
        values:
          "id,code,name,manufacturer,manufacturer__name,os,os__name,battery,battery__code,screen,cpu,cpu__name,gpu,gpu__name,camera_system,camera_system__code,sim,sim__code,network_technology,network_technology__name,charging_technology,charging_technology__code,external_storage,external_storage__max_capacity,ip_rating,ip_rating__code,design,create_time,update_time",
        distinct_values: {
          label: { type: "Concat", field: ["name", "os__name", "manufacturer__name"] },
        },
        summary: "annotate",
      },
    },
    {
      name: "Product_Variant",
      url: "data/Product_Variant/",
      url_detail: "data-detail/Product_Variant/",
      params: {},
    },
    {
      name: "productdocument",
      commit: "productdocument",
      url: "data/Product_Document/",
      url_detail: "data-detail/Product_Document/",
      params: {},
    },
    {
      name: "productstatus",
      url: "data/Product_Status/",
      url_detail: "data-detail/Product_Status/",
      params: {
        sort: "name",
        values: "id,code,name,color,index,sale_status,create_time",
      },
    },
    {
      name: "producttype",
      url: "data/Product_Type/",
      url_detail: "data-detail/Product_Type/",
      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "salestatus",
      url: "data/Sale_Status/",
      url_detail: "data-detail/Sale_Status/",
      params: {
        values: "id,code,name,color,index,create_time",
      },
    },
    {
      name: "project",
      url: "data/Project/",
      url_detail: "data-detail/Project/",
      params: {
        values: "id,code,name,investor,status,create_time,update_time",
      },
    },
    {
      name: "zonetype",
      url: "data/Zone_Type/",
      url_detail: "data-detail/Zone_Type/",
      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "direction",
      url: "data/Direction/",
      url_detail: "data-detail/Direction/",
      params: {
        values: "id,code,name,create_time",
      },
    },
    {
      name: "settingclass",
      commit: "settingclass",
      url: "data/Setting_Class/",
      url_detail: "data-detail/Setting_Class/",
      params: {},
    },
    {
      name: "user",
      url: "data/User/",
      url_detail: "data-detail/User/",
      params: {
        sort: "-id",
        values:
          "id,auth_method__code,blocked,auth_status__code,username,register_method__code,fullname,type,type__code,type__name,create_time,create_time__date,auth_method,auth_status,register_method,create_time,update_time",
        distinct_values: {
          label: { type: "Concat", field: ["username", "fullname"] },
        },
        summary: "annotate",
      },
    },
    { name: "gethash", url: "get-hash/", params: {} },
    {
      name: "login",
      url: "login/",
      params: {
        values:
          "id,username,password,avatar,fullname,display_name,type,type__code,type__name,blocked,block_reason,block_reason__code,block_reason__name,blocked_by,last_login,auth_method,auth_method__code,auth_method__name,auth_status,auth_status__code,auth_status__name,register_method,register_method__code,register_method__name,create_time,update_time",
      },
    },
    {
      name: "reservation",
      commit: "reservation",
      url: "data/Reservation/",
      url_detail: "data-detail/Reservation/",
      params: {},
    },
    {
      name: "settingtype",
      commit: "settingtype",
      url: "data/Setting_Type/",
      url_detail: "data-detail/Setting_Type/",
      params: {},
    },
    {
      name: "colorchoice",
      commit: "colorchoice",
      url: "data/Color_Choice/",
      url_detail: "data-detail/Color_Choice/",
      params: { sort: "id" },
    },
    {
      name: "filterchoice",
      commit: "filterchoice",
      url: "data/Filter_Choice/",
      url_detail: "data-detail/Filter_Choice/",
      params: { sort: "id" },
    },
    {
      name: "datatype",
      commit: "datatype",
      url: "data/Data_Type/",
      url_detail: "data-detail/Data_Type/",
      params: { sort: "id" },
    },
    {
      name: "textalign",
      commit: "textalign",
      url: "data/Text_Align/",
      url_detail: "data-detail/Text_Align/",
      params: { sort: "id" },
    },
    {
      name: "placement",
      commit: "placement",
      url: "data/Placement/",
      url_detail: "data-detail/Placement/",
      params: { sort: "id" },
    },
    {
      name: "colorscheme",
      commit: "colorscheme",
      url: "data/Color_Scheme/",
      url_detail: "data-detail/Color_Scheme/",
      params: { sort: "id" },
    },
    {
      name: "textcolor",
      commit: "textcolor",
      url: "data/Text_Color/",
      url_detail: "data-detail/Text_Color/",
      params: { sort: "id" },
    },
    {
      name: "filtertype",
      commit: "filtertype",
      url: "data/Filter_Type/",
      url_detail: "data-detail/Filter_Type/",
      params: { sort: "id" },
    },
    {
      name: "sorttype",
      commit: "sorttype",
      url: "data/Sort_Type/",
      url_detail: "data-detail/Sort_Type/",
      params: { sort: "id" },
    },
    {
      name: "tablesetting",
      commit: "tablesetting",
      url: "data/Table_Setting/",
      url_detail: "data-detail/Table_Setting/",
      params: { sort: "id", values: "id,code,name,detail" },
    },
    {
      name: "settingchoice",
      commit: "settingchoice",
      url: "data/Setting_Choice/",
      url_detail: "data-detail/Setting_Choice/",
      params: { sort: "id" },
    },
    {
      name: "menuchoice",
      commit: "menuchoice",
      url: "data/Menu_Choice/",
      url_detail: "data-detail/Menu_Choice/",
      params: {},
    },
    {
      name: "moneyunit",
      commit: "moneyunit",
      url: "data/Money_Unit/",
      url_detail: "data-detail/Money_Unit/",
      params: {},
    },
    {
      name: "legaltype",
      commit: "legaltype",
      url: "data/Legal_Type/",
      url_detail: "data-detail/Legal_Type/",
      params: { page: -1 },
    },
    {
      name: "sex",
      commit: "sex",
      url: "data/Sex/",
      url_detail: "data-detail/Sex/",
      params: {},
    },
    {
      name: "usertype",
      commit: "UserType",
      url: "data/User_Type/",
      url_detail: "data-detail/User_Type/",
      params: {},
    },

    {
      name: "executionmethod",
      commit: "executionmethod",
      url: "data/Execution_Method/",
      url_detail: "data-detail/Execution_Method/",
      params: {},
    },
    {
      name: "customerpeople",
      url: "data/Customer_People/",
      url_detail: "data-detail/Customer_People/",
      params: {
        values:
          "people__legal_code,id,customer,people,people__code,people__address,people__fullname,people__phone,relation,relation__code,relation__name,relation__en,create_time",
      },
    },
    {
      name: "legalrep",
      url: "data/Legal_Rep/",
      url_detail: "data-detail/Legal_Rep/",
      params: {
        values:
          "id,organization,people,people__code,people__address,people__fullname,people__phone,relation,relation__code,relation__name,relation__en,create_time",
      },
    },
    {
      name: "customerfile",
      url: "data/Customer_File/",
      url_detail: "data-detail/Customer_File/",
      params: { values: "id,ref,file,file__name,file__file" },
    },
    {
      name: "customertype",
      url: "data/Customer_Type/",
      url_detail: "data-detail/Customer_Type/",
      params: { values: "id,code,name,create_time" },
    },
    {
      name: "peoplefile",
      url: "data/People_File/",
      url_detail: "data-detail/People_File/",
      params: { values: "id,ref,file,file__name,file__file" },
    },
    {
      name: "collaboratorfile",
      url: "data/Collaborator_File/",
      url_detail: "data-detail/Collaborator_File/",
      params: { values: "id,ref,file,file__name,file__file" },
    },
    {
      name: "applicationfile",
      url: "data/Application_File/",
      url_detail: "data-detail/Application_File/",
      params: {
        values:
          "id,ref,file,file__name,file__file,file__type__code,file__type__name,file__doc_type__code,file__doc_type__name,file__doc_type__en",
      },
    },
    {
      name: "useraction",
      url: "data/User_Action/",
      url_detail: "data-detail/User_Action/",
      params: {
        values:
          "id,action,action__code,action__name,action__message,action__image,action__file,action__link,user,message,image,file,link,create_time",
      },
    },
    {
      name: "relation",
      commit: "relation",
      url: "data/Relation/",
      url_detail: "data-detail/Relation/",
      params: { sort: "id" },
    },
    {
      name: "company",
      url: "data/Company/",
      url_detail: "data-detail/Company/",
      params: {
        values:
          "id,country,website,email,code,phone,shortname,fullname,address,create_time,update_time,creator,creator__fullname,updater,updater__fullname",
      },
    },
    {
      name: "exportlog",
      url: "data/Export_Log/",
      url_detail: "data-detail/Export_Log/",
      params: {},
    },
    {
      name: "bank",
      url: "data/Bank/",
      url_detail: "data-detail/Bank/",
      params: {},
    },
    { name: "exportcsv", url: "exportcsv/", params: {} },
    {
      name: "internalentry",
      url: "data/Internal_Entry/",
      url_detail: "data-detail/Internal_Entry/",
      params: {
        sort: "-id",
        values:
          "product__trade_code,allocation_amount,allocation_remain,allocation_detail,id,customer__fullname,product__trade_code,customer,customer__code,product,product__code,ref,category,category__code,category__name,account__currency__code,balance_before,balance_after,code,account,account__code,account__branch__name,account__type__name,date,amount,content,inputer,inputer__fullname,approver,approver__fullname,create_time,update_time,type,type__code,type__name",
      },
    },
    {
      name: "applicationrights",
      url: "data/Application_Rights/",
      url_detail: "data-detail/Application_Rights/",
      params: { sort: "-id" },
    },

    {
      name: "productfile",
      url: "data/Product_File/",
      url_detail: "data-detail/Product_File/",
      params: { values: "id,product,file,create_time" },
    },
    {
      name: "Email_Template",
      url: "data/Email_Template/",
      url_detail: "data-detail/Email_Template/",
      params: {},
    },
    {
      name: "projectfile",
      url: "data/Project_File/",
      url_detail: "data-detail/Project_File/",
      params: { values: "id,project,file,create_time" },
    },
    {
      name: "issuedplace",
      url: "data/Issued_Place/",
      url_detail: "data-detail/Issued_Place/",
      params: { values: "id,code,name,create_time" },
    },
    {
      name: "dealer",
      url: "data/Dealer/",
      url_detail: "data-detail/Dealer/",
      params: {
        values:
          "id,count_sale,code,name,phone,address,email,create_time,sale_amount,pay_sale,commission_amount,pay_commission,commission_remain,batch_date",
      },
    },
    {
      name: "layersetting",
      url: "data/Layer_Setting/",
      url_detail: "data-detail/Layer_Setting/",
      params: { values: "id,code,name,detail,user,create_time,update_time" },
    },
    {
      name: "grouprights",
      commit: "grouprights",
      url: "data/Group_Rights/",
      url_detail: "data-detail/Group_Rights/",
      params: {
        values: "id,setting,setting__vi,setting__code,setting__category,group,group__name,is_edit,create_time",
        sort: "-id",
      },
    },
    {
      name: "discountmethod",
      commit: "discountmethod",
      url: "data/Discount_Method/",
      url_detail: "data-detail/Discount_Method/",
      params: { sort: "-id" },
    },
    {
      name: "emailtemplate",
      url: "data/Email_Template/",
      url_detail: "data-detail/Email_Template/",
      params: { values: "id,name,content,create_time,update_time" },
    },
    {
      name: "gift",
      commit: "gift",
      url: "data/Gift/",
      url_detail: "data-detail/Gift/",
      params: { sort: "-id" },
    },
    {
      name: "transactiongift",
      commit: "transactiongift",
      url: "data/Transaction_Gift/",
      url_detail: "data-detail/Transaction_Gift/",
      params: {},
    },
    {
      name: "invoice",
      commit: "invoice",
      url: "data/Invoice/",
      url_detail: "data-detail/Invoice/",
      params: {},
    },
    {
      name: "Manufacturer",
      url: "data/Manufacturer/",
      url_detail: "data-detail/Manufacturer/",
      params: {},
    },
    {
      name: "OS",
      url: "data/OS/",
      url_detail: "data-detail/OS/",
      params: {
        sort: "name",
      },
    },
    {
      name: "Battery",
      url: "data/Battery/",
      url_detail: "data-detail/Battery/",
      params: {},
    },
    {
      name: "Screen",
      url: "data/Screen/",
      url_detail: "data-detail/Screen/",
      params: {
        values: "id,code,resolution,standard,technology,size,create_time",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["resolution", "standard", "technology"],
          },
        },
        summary: "annotate",
      },
    },
    {
      name: "CPU",
      url: "data/CPU/",
      url_detail: "data-detail/CPU/",
      params: {},
    },
    {
      name: "GPU",
      url: "data/GPU/",
      url_detail: "data-detail/GPU/",
      params: {},
    },
    {
      name: "Camera_System",
      url: "data/Camera_System/",
      url_detail: "data-detail/Camera_System/",
      params: {},
    },
    {
      name: "SIM",
      url: "data/SIM/",
      url_detail: "data-detail/SIM/",
      params: {},
    },
    {
      name: "Network_Technology",
      url: "data/Network_Technology/",
      url_detail: "data-detail/Network_Technology/",
      params: {},
    },
    {
      name: "Charging_Technology",
      url: "data/Charging_Technology/",
      url_detail: "data-detail/Charging_Technology/",
      params: {},
    },
    {
      name: "External_Storage",
      url: "data/External_Storage/",
      url_detail: "data-detail/External_Storage/",
      params: {},
    },
    {
      name: "IP_Rating",
      url: "data/IP_Rating/",
      url_detail: "data-detail/IP_Rating/",
      params: {},
    },
    {
      name: "Design",
      url: "data/Design/",
      url_detail: "data-detail/Design/",
      params: {
        values: "id,code,frame_material,back_material,create_time",
        distinct_values: {
          label: {
            type: "Concat",
            field: ["frame_material", "back_material"],
          },
        },
        summary: "annotate",
      },
    },
    {
      name: "Color",
      url: "data/Color/",
      url_detail: "data-detail/Color/",
      params: {},
    },
    {
      name: "RAM",
      url: "data/RAM/",
      url_detail: "data-detail/RAM/",
      params: {
        sort: "capacity",
      },
    },
    {
      name: "Internal_Storage",
      url: "data/Internal_Storage/",
      url_detail: "data-detail/Internal_Storage/",
      params: {
        sort: "capacity",
      },
    },
    {
      name: "IMEI",
      url: "data/IMEI/",
      url_detail: "data-detail/IMEI/",
      params: {},
    },
    {
      name: "Product_Image",
      url: "data/Product_Image/",
      url_detail: "data-detail/Product_Image/",
      params: {},
    },
  ];
  const { $copy, $clone, $updateSeriesFields, $snackbar, $store, $remove, $dialog } = nuxtApp;

  const requestLogin = function () {
    $store.commit("login", undefined);
    $store.commit("layersetting", undefined);
    window.location.href = `https://${mode === "dev" ? "dev." : ""}login.utopia.com.vn/signin?module=${module}&link=${window.location.origin}`;
  };

  const getpath = function (name) {
    return name ? paths.find((v) => v.name === name).url : path;
  };

  const findapi = function (name) {
    const result = Array.isArray(name)
      ? apis.filter((v) => name.findIndex((x) => v.name === x) >= 0)
      : apis.find((v) => v.name === name);

    if (!result) {
      console.error(`API "${name}" doesn't exist`);
    }

    return $copy(result);
  };

  const readyapi = function (apiNames) {
    const apisWithReady = [];
    apiNames.forEach((apiName) => {
      const found = apis.find((v) => v.name === apiName);
      if (found) {
        const apiWithReady = {
          ...$copy(found),
          ready: Boolean($store[apiName]),
        };
        apisWithReady.push(apiWithReady);
      }
    });
    return apisWithReady;
  };

  // get data
  const getapi = async function (list) {
    try {
      let arr = list.map((v) => {
        let found = apis.find((api) => api.name === v.name);
        let url = (v.path ? paths.find((x) => x.name === v.path).url : path) + (v.url ? v.url : found.url);
        let params = v.params ? v.params : found.params === undefined ? {} : found.params;
        params.login = $store.login ? $store.login.id : undefined;
        return { url, params };
      });
      let data = await Promise.all(arr.map((v) => $fetch(v.url, { params: v.params })));
      data.map((v, i) => {
        list[i].data = v;
        if (list[i].commit) {
          let data = v.rows ? v.rows : v;
          $store.commit(list[i].commit, data);
        }
      });
      return list;
    } catch (err) {
      console.log(err);
      return "error";
    }
  };

  // insert data
  const insertapi = async function (name, data, values, notify) {
    try {
      const found = findapi(name);
      const curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
      let rs;
      if (Array.isArray(data)) {
        rs = await $fetch(`${curpath}import-data/${found.url.substring(5, found.url.length - 1)}/`, {
          method: "POST",
          body: data,
          params: { values, action: "import" },
        });
      } else {
        rs = await $fetch(`${curpath}${found.url}`, {
          method: "POST",
          body: data,
          params: { values },
        });
      }
      // update store
      if (found.commit) {
        if ($store[found.commit]) {
          const copy = $copy($store[found.commit]);
          const rows = Array.isArray(rs) ? rs : [rs];
          rows.forEach((v) => {
            if (v.id && !v.error) {
              let idx = copy.findIndex((x) => x.id === v.id);
              if (idx >= 0) copy[idx] = v;
              else copy.push(v);
            }
          });
          $store.commit(found.commit, copy);
        }
      }
      if (notify !== false) {
        $store.lang === "en"
          ? $snackbar("Data has been successfully saved to the system.", "Success")
          : $snackbar("Dữ liệu đã được lưu vào hệ thống", "Success");
      }
      return rs;
    } catch (err) {
      console.log(err);
      return "error";
    }
  };

  // update api
  const updateapi = async function (name, data, values, notify) {
    try {
      let found = findapi(name);
      let curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
      let updateUrl = found.url_detail ? found.url_detail : found.url;
      let rs = await $fetch(`${curpath}${updateUrl}${data.id}/`, {
        method: "PUT",
        body: data,
        params: { values: values || found.params.values },
      });
      if (found.commit) {
        let index = $store[found.commit] ? $store[found.commit].findIndex((v) => v.id === rs.id) : -1;
        if (index >= 0) {
          var copy = $copy($store[found.commit]);
          if (Array.isArray(rs) === false) copy[index] = rs;
          else {
            rs.forEach((v) => {
              let index = copy.findIndex((v) => v.id === v.id);
              if (index >= 0) copy[index] = v;
            });
          }
          $store.commit(found.commit, copy);
        }
      }
      if (notify !== false) {
        $store.lang === "en"
          ? $snackbar("Data has been successfully saved to the system.", "Success")
          : $snackbar("Dữ liệu đã được lưu vào hệ thống", "Success");
      }
      return rs;
    } catch (err) {
      console.log(err);
      return "error";
    }
  };

  // patch api
  const patchapi = async function (name, data, values, notify) {
    try {
      let found = findapi(name);
      let curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
      let updateUrl = found.url_detail ? found.url_detail : found.url;

      const rs = await $fetch(`${curpath}${updateUrl}${data.id}/`, {
        method: "PATCH",
        body: data,
        params: { values: values || found.params?.values },
      });

      if (notify !== false) {
        $store.lang === "en"
          ? $snackbar("Data has been successfully saved to the system.", "Success")
          : $snackbar("Dữ liệu đã được lưu vào hệ thống", "Success");
      }
      return rs;
    } catch (err) {
      console.log(err);
      return "error";
    }
  };

  const findpage = function (arr) {
    var copy = $copy($store.pagetrack);
    var doFind = function () {
      let found = undefined;
      for (let i = 1; i <= 30; i++) {
        let name = `pagedata${i}`;
        if (!copy[name]) {
          found = name;
          copy[name] = true;
          break;
        }
      }
      if (!found) console.log("pagename not found");
      return found;
    };
    let result;
    if (arr) {
      result = [];
      arr.map((v) => {
        result.push({ name: v, value: doFind() });
      });
    } else {
      result = doFind(copy);
    }
    $store.commit("pagetrack", copy);
    return result;
  };

  const getpage = function (showFilter) {
    return {
      data: [],
      fields: [],
      filters: [],
      update: undefined,
      action: undefined,
      filterby: undefined,
      api: { full_data: true },
      origin_api: { full_data: true },
      tablesetting: undefined,
      setting: undefined,
      tabfield: true,
      setpage: {},
      showFilter: !showFilter ? true : showFilter,
    };
  };

  const setpage = function (pagename, row, api) {
    let json = row.detail;
    let fields = $updateSeriesFields(json.fields);
    let copy = $store[pagename] || getpage();
    copy.fields = fields;
    copy.setting = $copy(row);
    if (json.filters) copy.filters = $copy(json.filters);
    if (json.tablesetting) copy.tablesetting = json.tablesetting;
    if (api) {
      let copyApi = $copy(api);
      delete copyApi.data;
      copyApi.full_data = api.data.full_data;
      copyApi.total_rows = api.data.total_rows;
      copy.api = copyApi;
      copy.origin_api = copy;
    }
    $store.commit(pagename, copy);
    return copy;
  };

  const getdata = async function (name, filter, params, first) {
    let found = findapi(name);
    if (params) found.params = params;
    else if (filter) found.params.filter = filter;
    let rs = await getapi([found]);
    let data = rs[0].data;
    if (data) {
      if (data.rows) {
        return first ? (data.rows.length > 0 ? data.rows[0] : undefined) : data.rows;
      } else {
        let rows = Array.isArray(data) ? data : [data];
        return first ? (rows.length > 0 ? rows[0] : data) : data;
      }
    } else {
      let rows = Array.isArray(data) ? data : [data];
      return first ? (rows.length > 0 ? rows[0] : data) : data;
    }
  };

  const subscribe = (name, filter, callback) => {
    const apiConfig = findapi(name);
    if (!apiConfig) {
      console.error(`[subscribe] API config for '${name}' not found.`);
      return;
    }

    const urlParts = apiConfig.url.split("/").filter((p) => p);
    // Capitalize the model name for the backend consumer
    const modelName = urlParts.length > 1 ? urlParts[1].charAt(0).toUpperCase() + urlParts[1].slice(1) : null;

    if (!modelName) {
      console.error(`[subscribe] Could not determine model name from URL for '${name}'.`);
      return;
    }

    const params = $clone(apiConfig.params) || {};

    // List of parameters that need to be stringified if they are objects
    const paramsToJSONify = ["filter_or", "exclude", "distinct_values", "calculation", "final_filter", "final_exclude"];

    // Apply the filter passed to subscribe function
    if (filter) {
      params.filter = JSON.stringify(filter);
    }

    // Stringify other dictionary-like parameters if they exist and are objects
    for (const key of paramsToJSONify) {
      if (params[key] && typeof params[key] === "object" && !Array.isArray(params[key])) {
        params[key] = JSON.stringify(params[key]);
      }
    }

    const payload = {
      name: modelName,
      params: params,
    };

    subscribeToData(payload, callback);
  };

  // insert row
  var insertrow = async function (name, data, values, pagename, notify) {
    let result = await insertapi(name, data, values, notify);
    if (result === "error" || !pagename || !$store[pagename]) return result;
    let copy = $clone($store[pagename]);
    copy.update = { refresh: true };
    $store.commit(pagename, copy);
    return result;
  };

  // update row
  const updaterow = async function (name, data, values, pagename, notify) {
    let result = await updateapi(name, data, values, notify);
    if (result === "error" || !pagename || !$store[pagename]) return result;
    let copy = $clone($store[pagename]);
    copy.update = { refresh: true };
    $store.commit(pagename, copy);
    return result;
  };

  // patch row
  const patchrow = async function (name, data, values, pagename, notify) {
    let result = await patchapi(name, data, values, notify);
    if (result === "error" || !pagename || !$store[pagename]) return result;
    let copy = $clone($store[pagename]);
    copy.update = { refresh: true };
    $store.commit(pagename, copy);
    return result;
  };

  // delete data
  const deleteapi = async function (name, id) {
    try {
      const found = findapi(name);
      let rs;
      if (!Array.isArray(id)) {
        rs = await $fetch(`${path}${found.url_detail}${id}`, {
          method: "delete",
        });
      } else {
        rs = await $fetch(`${path}import-data/${found.url.substring(5, found.url.length - 1)}/`, id, {
          params: { action: "delete" },
        });
      }
      if (found.commit) {
        const copy = $copy($store[found.commit]);
        if (!Array.isArray(id)) {
          const index = copy.findIndex((v) => v.id === id);
          if (index >= 0) $remove(copy, index);
        } else {
          rs.forEach((element) => {
            const index = copy.findIndex((v) => v.id === element.id);
            if (index >= 0) $remove(copy, index);
          });
        }
        $store.commit(found.name, copy);
      }
      return id;
    } catch (err) {
      console.error(err);
      if (err.response) {
        let content = `<span>Đã xảy ra lỗi, xóa dữ liệu không thành công</span>`;
        if (err.response.data)
          content += `<p class="mt-2 has-text-grey-dark"> 
          <sapn class="icon-text">Chi tiết<SvgIcon class="ml-1" v-bind="{name: 'right.svg', type: 'dark', size: 20}"></SvgIcon></span></p>
          <p class="mt-2 has-text-grey-dark">${JSON.stringify(err.response.data)}</p>`;
        $dialog(content, "Lỗi", "Error");
      }
      return "error";
    }
  };

  // delete row
  const deleterow = async function (name, id, pagename) {
    let result = await deleteapi(name, id);
    if (result === "error" || !pagename || !$store[pagename]) return result;
    let copy = $clone($store[pagename]);
    copy.update = { refresh: true };
    $store.commit(pagename, copy);
    return result;
  };

  // update page
  const updatepage = function (pagename, row, action) {
    let copy = $clone($store[pagename]);
    let rows = Array.isArray(row) ? row : [row];
    rows.map((x) => {
      let idx = copy.data.findIndex((v) => v.id === x.id);
      if (action === "delete") {
        if (idx >= 0) $remove(copy.data, idx);
      } else {
        idx >= 0 ? (copy.data[idx] = x) : copy.data.unshift(x);
      }
    });
    copy.update = { data: copy.data };
    $store.commit(pagename, copy);
  };

  const buildFileUrl = (file) => {
    if (!file || typeof file !== "string") {
      console.error(`Invalid file__file: ${file}`);
      return;
    }
    return `${getpath()}static/files/${encodeURIComponent(file)}`;
  };

  const generateDocument = async (params) => {
    const apiBaseUrl = path;

    const url = new URL(`${apiBaseUrl}generate-document/`);
    if (params) {
      for (const key in params) {
        if (Object.hasOwnProperty.call(params, key)) {
          const value = params[key];
          if (value !== undefined && value !== null) {
            url.searchParams.append(key, value);
          }
        }
      }
    }

    try {
      const response = await $fetch(url.toString(), {
        method: "GET",
      });

      if (response && response.pdf) {
        const pdfUrl = `${apiBaseUrl}static/contract/${response.pdf}`;
        return { success: true, pdfUrl: pdfUrl, data: response };
      } else {
        console.error("generateDocument: Định dạng phản hồi API không hợp lệ.", response);
        return {
          success: false,
          error: "Định dạng phản hồi API không hợp lệ.",
        };
      }
    } catch (error) {
      console.error("Lỗi khi tạo tài liệu:", error);
      return { success: false, error: error.data?.message || error.message };
    }
  };

  const accountEntry = async (params) => {
    const apiBaseUrl = path;

    try {
      const response = await $fetch(`${apiBaseUrl}account-entry/`, {
        method: "POST",
        body: params,
        headers: {
          "Content-Type": "application/json",
        },
      });

      if (response) {
        return { success: true, data: response };
      } else {
        console.error("Định dạng phản hồi API không hợp lệ.", response);
        return {
          success: false,
          error: "Định dạng phản hồi API không hợp lệ.",
        };
      }
    } catch (error) {
      console.error("Lỗi khi tạo accountEntry:", error);
      return { success: false, error: error.data?.message || error.message };
    }
  };

  /**
   * @param {'edit' | 'view'} right
   * @param {{ code?: string, category?: string }} options
   * `code` & `category` from `Biz_Setting`
   * - If passed options, returns edit rights for `code` (useful for components used in modals in many different tabs)
   * - If not passed, returns edit rights for current tab & subtab
   * @returns {boolean}
   */
  const getEditRights = (right = "edit", { code, category } = {}) => {
    if (!["edit", "view"].includes(right)) throw new Error(`right ${right} is not one of ['edit', 'view']`);

    const getRight = (rightObj) => {
      return right === "edit" ? rightObj && rightObj.is_edit : Boolean(rightObj);
    };

    if ($store.rights.length === 0) return true; // full rights

    if (code && category) {
      // if passed, must pass both
      const foundRight = $store.rights.find(
        ({ setting__category, setting__code }) => setting__category === category && setting__code === code,
      );
      return getRight(foundRight);
    } else {
      const { tab, subtab } = $store.tabinfo;
      let isTabEdit;
      let isSubTabEdit;

      const tabRight = $store.rights.find((rights) => rights.setting === tab.id);
      isTabEdit = getRight(tabRight);

      if (!subtab) isSubTabEdit = false;
      else {
        const subTabRight = $store.rights.find((rights) => rights.setting === subtab.id);
        isSubTabEdit = getRight(subTabRight);
      }

      return isTabEdit || isSubTabEdit;
    }
  };

  // --- WebSocket Integration ---
  let socket = null;
  const requests = {}; // Store callbacks for subscription responses

  const connectWebSocket = () => {
    if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
      return;
    }

    // Use wss for https, ws for http
    const wsProtocol = window.location.protocol === "https:" ? "wss:" : "wss:";
    // Construct base URL without http/https protocol
    const baseUrl = path.replace(/^https?:\/\//, "");
    const wsUrl = `${wsProtocol}//${baseUrl}ws/data/`;

    socket = new WebSocket(wsUrl);

    socket.onopen = () => {
      console.log("WebSocket connection established");
    };

    socket.onmessage = (event) => {
      const response = JSON.parse(event.data);

      // Handle initial subscription responses with specific callbacks
      if (response.type === "subscription_response" && response.request_id && requests[response.request_id]) {
        const callback = requests[response.request_id];
        callback(response.data);
        delete requests[response.request_id]; // Clean up callback after use
      } else {
        // For all other messages (like realtime_update), dispatch a global event
        // This decouples the plugin from the store logic
        window.dispatchEvent(new CustomEvent("ws_message", { detail: response }));
      }
    };

    socket.onclose = (event) => {
      console.log("WebSocket connection closed:", event);
      socket = null;
      // Attempt to reconnect after a delay
      setTimeout(connectWebSocket, 5000);
    };

    socket.onerror = (error) => {
      console.error("WebSocket error:", error);
    };
  };

  const subscribeToData = (payload, callback) => {
    if (!socket || socket.readyState !== WebSocket.OPEN) {
      console.warn("WebSocket is not connected. Attempting to connect and retry.");
      connectWebSocket();
      // Retry subscription after a short delay
      setTimeout(() => subscribeToData(payload, callback), 1000);
      return;
    }

    const requestId = `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    if (callback) {
      requests[requestId] = callback;
    }

    const request = {
      action: "subscribe",
      request_id: requestId,
      payload: payload,
    };

    socket.send(JSON.stringify(request));
    console.log("[WebSocket] Sent subscription request:", request);
  };

  return {
    provide: {
      getpath,
      findapi,
      readyapi,
      getapi,
      getdata,
      subscribe,
      insertapi,
      updateapi,
      patchapi,
      updaterow,
      findpage,
      getpage,
      setpage,
      insertrow,
      deleteapi,
      deleterow,
      updatepage,
      requestLogin,
      buildFileUrl,
      generateDocument,
      accountEntry,
      getEditRights,
      connectWebSocket,
      subscribeToData,
      mode,
    },
  };
});
