import md5 from 'blueimp-md5';
import { Service, Domain, Invoice, Ticket, WHMCSConfig, ClientStats, CartItem, StoreGroup, StoreProduct, PaymentMethod, ServiceAddon, Department, TicketDetail, InvoiceDetail, UpgradeOption, UpgradeCalculation, User, EmailMessage } from '../types';

// Utility to handle WHMCS's inconsistent array/object responses
const normalizeWHMCSArray = (data: any): any[] => {
  if (!data) return [];
  if (Array.isArray(data)) return data;
  return [data];
};

// Helper to get custom field value across WHMCS API variations
const getCustomFieldValue = (fields: any, name: string): string => {
  if (!fields) return '';
  const fieldList = normalizeWHMCSArray(fields.customfield || fields);
  const field = fieldList.find((f: any) =>
    (f.name && f.name.toLowerCase() === name.toLowerCase()) ||
    (f.fieldname && f.fieldname.toLowerCase() === name.toLowerCase())
  );
  return field?.value || '';
};

// Helper to get config option value (e.g., Datacenter, Rack Space)
const getConfigOptionValue = (options: any, name: string): string => {
  if (!options) return '';
  const optionList = normalizeWHMCSArray(options.configoption || options);
  const found = optionList.find((o: any) =>
    (o.option && o.option.trim() === name.trim()) ||
    (o.name && o.name.trim() === name.trim())
  );
  return found?.value || '';
};

let cachedConfig: WHMCSConfig | null = null;
const BACKEND_URL = 'http://localhost:3001/api/config';

export const getProductMapping = async (): Promise<{ vps: number[], dedicated: number[], colocation: number[], hosting: number[] }> => {
  try {
    const res = await fetch(`${BACKEND_URL}/group_mapping`);
    const data = await res.json();
    return data || { vps: [], dedicated: [], colocation: [], hosting: [] };
  } catch (err) {
    console.error('Failed to fetch product mapping', err);
    return { vps: [], dedicated: [], colocation: [], hosting: [] };
  }
};

let initPromise: Promise<void> | null = null;

export const getWHMCSConfig = (): WHMCSConfig => {
  if (cachedConfig) return cachedConfig;

  const stored = localStorage.getItem('whmcs_config');
  if (stored) {
    try {
      return JSON.parse(stored);
    } catch (e) { }
  }

  return {
    url: '',
    apiIdentifier: '',
    apiSecret: ''
  };
};

export const initializeWHMCS = async (): Promise<void> => {
  if (initPromise) return initPromise;

  initPromise = (async () => {
    try {
      const res = await fetch(`${BACKEND_URL}/whmcs_api`);
      const data = await res.json();
      if (data && data.url) {
        cachedConfig = {
          url: data.url,
          apiIdentifier: '', // Secure: not stored on frontend
          apiSecret: ''      // Secure: not stored on frontend
        };
        localStorage.setItem('whmcs_config', JSON.stringify(cachedConfig));
        console.log('[WHMCS-INIT] Config loaded from Backend (Secure)');
      }
    } catch (err) {
      console.warn('[WHMCS-INIT] Backend config unavailable, using disk cache', err);
    }
  })();

  return initPromise;
};

export const saveWHMCSConfig = (config: WHMCSConfig): void => {
  localStorage.setItem('whmcs_config', JSON.stringify(config));
};

export const getWHMCSBaseUrl = (): string => {
  const config = getWHMCSConfig();
  let url = config.url;
  if (!url) return '';
  if (url.endsWith('/includes/api.php')) {
    url = url.replace('/includes/api.php', '');
  } else if (url.endsWith('/api.php')) {
    url = url.replace('/api.php', '');
  }
  return url.replace(/\/$/, '');
};

/**
 * All WHMCS API calls now go through our local backend proxy (port 3001)
 * to avoid CORS issues when calling WHMCS directly from the browser.
 */
export const callWHMCS = async (action: string, params: any = {}) => {
  try {
    const API_BASE = '/api/proxy/whmcs';
    const response = await fetch(API_BASE, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ action, params })
    });

    let data;
    try {
      data = await response.json();
    } catch (e) {
      if (!response.ok) {
        throw new Error(`Proxy Error: ${response.status} ${response.statusText}`);
      }
      throw new Error('Failed to parse API response');
    }

    if (!response.ok) {
      return {
        result: 'error',
        message: data?.message || `Proxy Error: ${response.status} ${response.statusText}`,
        status: response.status
      };
    }

    if (!data) {
      return { result: 'error', message: 'Empty response from API' };
    }

    if (data.result === 'error') {
      console.warn(`WHMCS API Business Error (${action}):`, data.message);
      // Pass through the message from the backend if available
      return { result: 'error', message: data.message || 'API request failed' };
    }
    return data;
  } catch (error) {
    console.error(`WHMCS API Proxy Error (${action}):`, error);
    // If it's a fetch/network error, report it cleanly
    return { result: 'error', message: error instanceof Error ? error.message : 'API connection failed' };
  }
};

export const validateLogin = async (email: string, password: string): Promise<{ result: string; userid?: number; passwordhash?: string; message?: string; auth_user_id?: number }> => {
  const cleanEmail = email.trim();
  const cleanPassword = password.trim();

  let response = await callWHMCS('ValidateLogin', {
    email: cleanEmail,
    password: cleanPassword,
    password2: cleanPassword
  });

  if (response.result === 'success') {
    let authUserId = response.user_id ? parseInt(response.user_id) : undefined;
    try {
      const clientDetails = await callWHMCS('GetClientsDetails', { email: cleanEmail, stats: false });
      if (clientDetails.result === 'success' && (clientDetails.client?.id || clientDetails.client_id)) {
        const resolvedClientId = clientDetails.client?.id || clientDetails.client_id;
        return {
          result: 'success',
          userid: parseInt(resolvedClientId),
          auth_user_id: authUserId
        };
      }
    } catch (e) {
      console.error('[Auth] Failed to resolve client ID', e);
    }
  }

  return response;
};

export const getClientStats = async (clientId: number): Promise<ClientStats | any> => {
  try {
    const response = await callWHMCS('GetClientsDetails', { clientid: clientId, stats: true });
    if (response.result === 'success') {
      const stats = response.stats;
      const client = response.client;
      const currency = client?.currency_code || (response.currencies?.currency?.[0]?.code) || 'USD';

      return {
        clientName: client?.fullname || `${client?.firstname} ${client?.lastname}`,
        email: client?.email,
        address1: client?.address1,
        city: client?.city,
        state: client?.state,
        postcode: client?.postcode,
        country: client?.country,
        currencyPrefix: response.currencies?.currency?.[0]?.prefix || '',
        currencySuffix: response.currencies?.currency?.[0]?.suffix || '',
        activeServices: parseInt(stats.productsnumactive) || 0,
        activeDomains: parseInt(stats.domainsnumactive) || 0,
        unpaidInvoices: parseInt(stats.numunpaidinvoices) || 0,
        overdueInvoices: parseInt(stats.numoverdueinvoices) || 0,
        ticketsActive: parseInt(stats.numactivetickets) || 0,
        creditBalance: parseFloat(stats.creditbalance) || 0,
        totalBalance: parseFloat(stats.numunpaidinvoices_amount) || 0,
        currency,
        userid: client?.id || clientId
      };
    }
    return { result: 'error', message: response.message || 'Failed to process client stats' } as any;
  } catch (error) {
    console.error('Error fetching client stats:', error);
    return { result: 'error', message: 'Connection to WHMCS failed' } as any;
  }
};

export const getServices = async (clientId: number): Promise<Service[]> => {
  try {
    const response = await callWHMCS('GetClientsProducts', { clientid: clientId });
    if (response.result === 'success' && response.products?.product) {
      const products = normalizeWHMCSArray(response.products.product);
      const mapping = await getProductMapping();

      // Fetch addons in parallel
      const addons = await getAddons(clientId);


      return products.map((p: any) => {
        let serviceType: Service['type'] = 'hosting';
        // WHMCS GetClientsProducts often returns groupid instead of gid
        const gid = parseInt(p.gid || p.groupid || p.productgroupid) || 0;
        const pid = parseInt(p.pid || p.productid);

        const matchingAddons = addons.filter(a => a.serviceId === parseInt(p.id));
        if (matchingAddons.length > 0) {

        }

        if (mapping.vps.includes(gid)) serviceType = 'vps';
        else if (mapping.dedicated.includes(gid)) serviceType = 'dedicated';
        else if (mapping.colocation.includes(gid)) serviceType = 'colocation';
        else if (mapping.hosting.includes(gid)) serviceType = 'hosting';
        else {
          // Fallback logic if GID is not explicitly mapped
          const nameLower = (p.productname || p.name || '').toLowerCase();
          const groupNameLower = (p.groupname || '').toLowerCase();

          if (nameLower.includes('vps') || nameLower.includes('virtual') || groupNameLower.includes('vps')) serviceType = 'vps';
          else if (nameLower.includes('dedicated') || groupNameLower.includes('dedicated')) serviceType = 'dedicated';
          else if (nameLower.includes('colocation') || nameLower.includes('rack') || groupNameLower.includes('colocation')) serviceType = 'colocation';
          else if (nameLower.includes('hosting') || nameLower.includes('reseller')) serviceType = 'hosting';
        }

        return {
          id: parseInt(p.id),
          productId: pid,
          groupId: gid || pid, // Fallback to pid in UI if gid is 0
          productName: p.productname || p.name,
          name: p.productname || p.name,
          domain: p.domain,
          status: p.status,
          nextDueDate: p.nextduedate,
          regDate: p.regdate,
          billingCycle: p.billingcycle,
          recurringAmount: parseFloat(p.amount) || 0,
          amount: parseFloat(p.amount) || 0,
          type: serviceType,
          serverIp: p.dedicatedip || p.ipaddress,
          ipAddress: p.dedicatedip || p.ipaddress,
          username: p.username,
          password: p.password,
          description: p.productname,
          // Extract specific fields for VPS and Colocation
          vpsId: getCustomFieldValue(p.customfields, 'vpsid'),
          serverId: parseInt(getCustomFieldValue(p.customfields, 'serverid')) || 0,
          rackSpace: getConfigOptionValue(p.configoptions, 'Rack Space Rented') || getCustomFieldValue(p.customfields, 'rackspace') || getCustomFieldValue(p.customfields, 'rack space'),
          datacenter: getConfigOptionValue(p.configoptions, 'Datacenter') || getCustomFieldValue(p.customfields, 'datacenter') || getCustomFieldValue(p.customfields, 'data center'),
          rackUnit: getConfigOptionValue(p.configoptions, 'Rack Unit') || getCustomFieldValue(p.customfields, 'rackunit') || getCustomFieldValue(p.customfields, 'rack unit'),
          allocatedPower: getConfigOptionValue(p.configoptions, 'Allocated Power') || getCustomFieldValue(p.customfields, 'allocatedpower') || getCustomFieldValue(p.customfields, 'power'),
          connectivity: getConfigOptionValue(p.configoptions, 'Connectivity') || getCustomFieldValue(p.customfields, 'connectivity') || getCustomFieldValue(p.customfields, 'network'),
          switchDetails: getConfigOptionValue(p.configoptions, 'Switch') || getCustomFieldValue(p.customfields, 'switchdetails') || getCustomFieldValue(p.customfields, 'switch'),
          switchPort: getConfigOptionValue(p.configoptions, 'Switch Port Number') || getCustomFieldValue(p.customfields, 'switchport') || getCustomFieldValue(p.customfields, 'port'),
          router: getConfigOptionValue(p.configoptions, 'Router') || getCustomFieldValue(p.customfields, 'router'),
          rackNumber: getConfigOptionValue(p.configoptions, 'Rack Number') || getCustomFieldValue(p.customfields, 'racknumber'),
          serviceType: getConfigOptionValue(p.configoptions, 'Service Type') || serviceType,
          addons: matchingAddons,
          setupStatus: p.status === 'Active' ? 'Completed' : 'Pending',
          diskLimit: p.disklimit || p.diskusage || '0',
          diskUsage: p.diskusage || '0',
          bwLimit: p.bwlimit || p.bandwidth || '0',
          bwUsage: p.bwusage || '0'
        };
      });
    }
    return [];
  } catch (error) {
    console.error('Error fetching services:', error);
    return [];
  }
};

export const getAddons = async (clientId: number): Promise<ServiceAddon[]> => {
  try {
    const response = await callWHMCS('GetClientsAddons', { clientid: clientId });
    if (response.result === 'success' && response.addons?.addon) {
      const addons = normalizeWHMCSArray(response.addons.addon);
      return addons.map((a: any) => ({
        id: a.id,
        serviceId: parseInt(a.serviceid),
        name: a.name,
        recurringAmount: parseFloat(a.recurring) || 0,
        billingCycle: a.billingcycle,
        status: a.status,
        nextDueDate: a.nextduedate,
        regDate: a.regdate
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching addons:', error);
    return [];
  }
};

export const getInvoices = async (clientId: number): Promise<Invoice[]> => {
  try {
    const response = await callWHMCS('GetInvoices', { userid: clientId, limitnum: 50 });
    if (response.result === 'success' && response.invoices?.invoice) {
      const invoices = normalizeWHMCSArray(response.invoices.invoice);
      return invoices.map((i: any) => ({
        id: i.id.toString(),
        date: i.date,
        dueDate: i.duedate,
        total: parseFloat(i.total),
        status: i.status,
        subtotal: parseFloat(i.subtotal),
        tax: parseFloat(i.tax),
        balance: parseFloat(i.balance)
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching invoices:', error);
    return [];
  }
};

export const getTickets = async (clientId: number): Promise<Ticket[]> => {
  try {
    const response = await callWHMCS('GetTickets', { clientid: clientId, limitnum: 50 });
    if (response.result === 'success' && response.tickets?.ticket) {
      const tickets = normalizeWHMCSArray(response.tickets.ticket);
      return tickets.map((t: any) => ({
        id: parseInt(t.id),
        tid: t.tid,
        subject: t.subject,
        department: t.deptname,
        status: t.status,
        priority: t.priority,
        lastReply: t.lastreply,
        lastUpdated: t.lastreply,
        date: t.date
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching tickets:', error);
    return [];
  }
};

export const getDomains = async (clientId: number): Promise<Domain[]> => {
  try {
    const response = await callWHMCS('GetClientsDomains', { clientid: clientId });
    if (response.result === 'success' && response.domains?.domain) {
      const domains = normalizeWHMCSArray(response.domains.domain);
      return domains.map((d: any) => ({
        id: parseInt(d.id),
        name: d.domainname || d.name,
        domain: d.domainname || d.name,
        status: d.status,
        nextDueDate: d.nextduedate,
        expiryDate: d.expirydate,
        registrationDate: d.registrationdate,
        regDate: d.registrationdate,
        recurringAmount: d.recurringamount,
        billingCycle: d.registrationperiod + ' Year(s)',
        registrarLock: d.registrar === "1" || d.donotrenew === "0",
        nameservers: []
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching domains:', error);
    return [];
  }
};

export const getInvoice = async (invoiceId: number): Promise<InvoiceDetail | null> => {
  try {
    const response = await callWHMCS('GetInvoice', { invoiceid: invoiceId });
    if (response.result === 'success') {
      const items = normalizeWHMCSArray(response.items?.item);
      const transactions = normalizeWHMCSArray(response.transactions?.transaction);

      return {
        id: response.invoiceid.toString(),
        date: response.date,
        dueDate: response.duedate,
        total: parseFloat(response.total),
        status: response.status,
        subtotal: parseFloat(response.subtotal),
        tax: parseFloat(response.tax),
        credit: parseFloat(response.credit),
        balance: parseFloat(response.balance),
        paymentMethod: response.paymentmethod,
        items: items.map((item: any) => ({
          id: item.id || 0,
          description: item.description,
          amount: parseFloat(item.amount) || 0,
          relid: item.relid,
          taxed: item.taxed === "1"
        })),
        transactions: transactions.map((t: any) => ({
          date: t.date,
          gateway: t.gateway,
          amount: parseFloat(t.amountin || t.amount || 0),
          transId: t.transid || t.id
        }))
      };
    }
    return null;
  } catch (error) {
    console.error('Error fetching invoice detail:', error);
    return null;
  }
};

export const getTicket = async (ticketId: number): Promise<TicketDetail | null> => {
  try {
    const response = await callWHMCS('GetTicket', { ticketid: ticketId });
    if (response.result === 'success') {
      const replies = normalizeWHMCSArray(response.replies?.reply);

      return {
        id: parseInt(response.ticketid),
        subject: response.subject,
        department: response.deptname || response.department,
        status: response.status,
        date: response.date,
        lastUpdated: response.lastreply,
        priority: response.priority === 'High' ? 'High' : response.priority === 'Medium' ? 'Medium' : 'Low',
        message: response.message,
        serviceId: response.serviceid ? parseInt(response.serviceid) : undefined,
        replies: replies.map((r: any) => ({
          id: parseInt(r.id),
          userId: r.userid || 0,
          name: r.name,
          email: r.email,
          date: r.date,
          message: r.message,
          admin: r.admin || false
        }))
      };
    }
    return null;
  } catch (error) {
    console.error('Error fetching ticket detail:', error);
    return null;
  }
};

export const addTicketReply = async (ticketId: number, clientId: number, message: string, attachments?: { name: string, base64: string }[]): Promise<boolean> => {
  try {
    const params: any = {
      ticketid: ticketId,
      message,
      clientid: clientId
    };

    if (attachments && attachments.length > 0) {
      attachments.forEach((file, index) => {
        params[`attachments[${index}][name]`] = file.name;
        params[`attachments[${index}][data]`] = file.base64;
      });
    }

    const response = await callWHMCS('AddTicketReply', params);
    return response.result === 'success';
  } catch (error) {
    console.error('Error adding ticket reply:', error);
    return false;
  }
};

export const openTicket = async (
  clientId: number,
  deptId: number,
  subject: string,
  message: string,
  priority: string = 'Medium',
  serviceId?: number,
  attachments?: { name: string, base64: string }[]
): Promise<any> => {
  try {
    const params: any = {
      clientid: clientId,
      deptid: deptId,
      subject,
      message,
      priority,
      serviceid: serviceId
    };

    if (attachments && attachments.length > 0) {
      attachments.forEach((file, index) => {
        params[`attachments[${index}][name]`] = file.name;
        params[`attachments[${index}][data]`] = file.base64;
      });
    }

    const response = await callWHMCS('OpenTicket', params);
    return response;
  } catch (error) {
    console.error('Error opening ticket:', error);
    return { result: 'error', message: 'Connection to WHMCS failed' };
  }
};

export const getSupportDepartments = async (): Promise<Department[]> => {
  try {
    const response = await callWHMCS('GetSupportDepartments');
    if (response.result === 'success' && (response.departments?.department || response.supportdepartments?.department)) {
      const depts = normalizeWHMCSArray(response.departments?.department || response.supportdepartments?.department);
      return depts.map((d: any) => ({
        id: parseInt(d.id),
        name: d.name,
        description: d.description
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching departments:', error);
    return [];
  }
};

export const getStoreData = async (): Promise<{ groups: StoreGroup[], products: StoreProduct[] }> => {
  try {
    const [groupsRes, productsRes] = await Promise.all([
      callWHMCS('GetProducts'),
      callWHMCS('GetProducts')
    ]);

    let groups: StoreGroup[] = [];
    let products: StoreProduct[] = [];

    if (groupsRes.result === 'success' && (groupsRes.groups?.group || groupsRes.productgroups?.group)) {
      const rawGroups = normalizeWHMCSArray(groupsRes.groups?.group || groupsRes.productgroups?.group);
      groups = rawGroups.map((g: any) => ({
        id: parseInt(g.id),
        name: g.name,
        description: g.description
      }));
    }

    if (productsRes.result === 'success' && productsRes.products?.product) {
      const rawProducts = normalizeWHMCSArray(productsRes.products.product);
      products = rawProducts.map((p: any) => {
        const pricing = p.pricing?.USD || p.pricing?.BDT || Object.values(p.pricing || {})[0] as any;
        return {
          id: parseInt(p.pid),
          groupId: parseInt(p.gid),
          name: p.name,
          description: p.description,
          price: parseFloat(pricing?.monthly?.replace(/[^\d.]/g, '') || pricing?.annually?.replace(/[^\d.]/g, '') || "0.00"),
          billingCycle: pricing?.monthly ? 'monthly' : 'annually',
          stockControl: p.stockcontrol === 'on',
          stockLevel: parseInt(p.stocklevel) || 0,
          showDomainOptions: p.showdomainoptions === '1',
          hasConfigOptions: p.configoptions === '1', // WHMCS often returns this flag
          pricing: pricing
        };
      });
    }

    return { groups, products };
  } catch (error) {
    console.error('Error fetching store data:', error);
    return { groups: [], products: [] };
  }
};

export const getProductConfigOptions = async (pid: number): Promise<any> => {
  try {
    // WHMCS GetProductConfigOptions usually needs a product ID
    const response = await callWHMCS('GetProductConfigOptions', { pid });
    if (response.result === 'success' && response.configoptions?.configoption) {
      return normalizeWHMCSArray(response.configoptions.configoption);
    }
    return [];
  } catch (error) {
    console.error('Error fetching config options:', error);
    return [];
  }
};

export const addOrder = async (clientId: number, cart: CartItem[]): Promise<any> => {
  try {
    const item = cart[0]; // Currently handling single item per order as per WHMCS basic flow

    const params: any = {
      clientid: clientId,
      pid: item.pid,
      billingcycle: item.billingCycle.toLowerCase(),
      paymentmethod: 'banktransfer' // Default, can be changed later by user
    };

    if (item.domain) {
      params.domain = item.domain;
      params.domaintype = item.domainType || 'existing';
      if (item.domainType === 'register' || item.domainType === 'transfer') {
        params.regperiod = item.regPeriod || 1;
      }
      if (item.domainType === 'transfer' && item.eppCode) {
        params.eppcode = item.eppCode;
      }
    }

    if (item.configOptions) {
      // WHMCS expects configoptions[id] = value
      Object.entries(item.configOptions).forEach(([key, value]) => {
        params[`configoptions[${key}]`] = value;
      });
    }

    if (item.customFields) {
      // WHMCS expects customfield[id] = value
      Object.entries(item.customFields).forEach(([key, value]) => {
        params[`customfields[${key}]`] = value;
      });
    }

    if (item.addons) {
      params.addons = item.addons.join(',');
    }

    const response = await callWHMCS('AddOrder', params);
    return response;
  } catch (error) {
    console.error('Error adding order:', error);
    return { result: 'error', message: 'Order processing failed' };
  }
};

export const updateClientDetails = async (clientId: number, details: any): Promise<any> => {
  try {
    const response = await callWHMCS('UpdateClient', {
      clientid: clientId,
      ...details
    });
    return response;
  } catch (error) {
    console.error('Error updating client details:', error);
    return { result: 'error', message: 'Update failed' };
  }
};

export const changeClientPassword = async (clientId: number, newPassword: string): Promise<boolean> => {
  try {
    const response = await callWHMCS('UpdateClient', {
      clientid: clientId,
      password: newPassword
    });
    return response.result === 'success';
  } catch (error) {
    console.error('Error changing client password:', error);
    return false;
  }
};

export const getEmailHistory = async (clientId: number): Promise<EmailMessage[]> => {
  try {
    const response = await callWHMCS('GetEmails', { clientid: clientId });
    if (response.result === 'success' && response.emails?.email) {
      const emails = normalizeWHMCSArray(response.emails.email);
      return emails.map((e: any) => ({
        id: parseInt(e.id),
        date: e.date,
        subject: e.subject,
        message: e.message
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching email history:', error);
    return [];
  }
};

export const getPaymentMethods = async (): Promise<PaymentMethod[]> => {
  try {
    const response = await callWHMCS('GetPaymentMethods');
    if (response.result === 'success' && response.paymentmethods?.paymentmethod) {
      const methods = normalizeWHMCSArray(response.paymentmethods.paymentmethod);
      return methods.map((m: any) => ({
        module: m.module,
        displayName: m.displayname
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching payment methods:', error);
    return [];
  }
};

export const getCountries = async (): Promise<Record<string, string>> => {
  // Static list for common use, or fetch if WHMCS provides a clean API for this
  return {
    "BD": "Bangladesh",
    "US": "United States",
    "GB": "United Kingdom",
    "CA": "Canada",
    "AU": "Australia"
  };
};

export const sendPasswordResetEmail = async (email: string): Promise<any> => {
  try {
    const response = await callWHMCS('SendPasswordResetEmail', { email });
    return response;
  } catch (error) {
    console.error('Error sending reset email:', error);
    return { result: 'error', message: 'Failed to send reset email' };
  }
};

export const changeUserPassword = async (clientId: number, newPassword: string, userId?: number, email?: string): Promise<any> => {
  // WHMCS UpdateClient can also change password
  return updateClientDetails(clientId, { password: newPassword });
};

export const getCompanyDetails = async (): Promise<any> => {
  // Use cached config if available (set by App.tsx or similar init)
  // Or fetch fresh if needed. For now, we'll try to fetch branding config.
  try {
    const res = await fetch('http://localhost:3001/api/config/branding');
    const branding = await res.json();
    return {
      companyName: branding.companyName || 'GotMyHost',
      address: branding.companyAddress || 'Dhaka, Bangladesh',
      logo: branding.appLogo || ''
    };
  } catch (error) {
    console.warn('Failed to fetch company details, using defaults', error);
    return {
      companyName: 'GotMyHost',
      address: 'Dhaka, Bangladesh',
      logo: ''
    };
  }
};

export const getUpgradeOptions = async (serviceId: number): Promise<UpgradeOption[]> => {
  try {
    const response = await callWHMCS('GetUpgradeProduct', { serviceid: serviceId });
    if (response.result === 'success' && response.upgradeproducts?.product) {
      const products = normalizeWHMCSArray(response.upgradeproducts.product);
      return products.map((p: any) => ({
        id: parseInt(p.pid),
        name: p.name,
        description: p.description || p.name,
        price: p.pricing?.USD?.monthly || p.pricing?.BDT?.monthly || "0.00",
        billingCycles: Object.keys(p.pricing?.USD || p.pricing?.BDT || {}).filter(k => k !== 'currency')
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching upgrade options:', error);
    return [];
  }
};

export const calculateUpgrade = async (serviceId: number, pid: number): Promise<UpgradeCalculation | null> => {
  try {
    // Note: WHMCS doesn't have a direct "CalculateUpgrade" API that returns a preview easily for all versions.
    // Usually handled by placing a dummy order or custom module.
    // For now, return a placeholder that the UI expects.
    return {
      subtotal: 0,
      tax: 0,
      credit: 0,
      balance: 0,
      total: 0,
      newRecurringAmount: 0
    };
  } catch (error) {
    console.error('Error calculating upgrade:', error);
    return null;
  }
};

export const processUpgrade = async (serviceId: number, pid: number): Promise<any> => {
  try {
    const response = await callWHMCS('AddOrder', {
      serviceid: serviceId,
      pid: pid,
      paymentmethod: 'banktransfer'
    });
    return response;
  } catch (error) {
    console.error('Error processing upgrade:', error);
    return { result: 'error', message: 'Upgrade process failed' };
  }
};



export const closeTicket = async (ticketId: number): Promise<boolean> => {
  try {
    const response = await callWHMCS('UpdateTicket', { ticketid: ticketId, status: 'Closed' });
    return response.result === 'success';
  } catch (error) {
    console.error('Error closing ticket:', error);
    return false;
  }
};

export const updateInvoicePaymentMethod = async (invoiceId: number, method: string): Promise<boolean> => {
  try {
    const response = await callWHMCS('UpdateInvoice', { invoiceid: invoiceId, paymentmethod: method });
    return response.result === 'success';
  } catch (error) {
    console.error('Error updating invoice payment method:', error);
    return false;
  }
};

export const registerClient = async (details: any): Promise<any> => {
  try {
    const response = await callWHMCS('AddClient', {
      ...details
    });
    return response;
  } catch (error) {
    console.error('Error registering client:', error);
    return { result: 'error', message: 'Registration failed' };
  }
};

export const getUsers = async (clientId: number): Promise<User[]> => {
  try {
    const response = await callWHMCS('GetUsers', { clientid: clientId });
    if (response.result === 'success' && response.users?.user) {
      const users = normalizeWHMCSArray(response.users.user);
      return users.map((u: any) => ({
        id: parseInt(u.id),
        name: `${u.firstname} ${u.lastname}`,
        email: u.email,
        lastLogin: u.lastlogin,
        isOwner: u.isowner === "1" || u.is_owner === "1" || false,
        permissions: u.permissions
      }));
    }
    return [];
  } catch (error) {
    console.error('Error fetching users:', error);
    return [];
  }
};

export const getClientDetails = async (clientId: number): Promise<any> => {
  try {
    const response = await callWHMCS('GetClientsDetails', { clientid: clientId });
    if (response.result === 'success') {
      return response.client;
    }
    return { result: 'error', message: response.message || 'Failed to fetch client details' };
  } catch (error) {
    console.error('Error fetching client details:', error);
    return { result: 'error', message: 'Connection to WHMCS failed' };
  }
};
