import express from "express";
import dotenv from "dotenv";
import path from "path";
import { fileURLToPath } from "url";
import soap from "soap";

dotenv.config();

const app = express();
app.use(express.json({ limit: "2mb" }));
app.use(express.urlencoded({ extended: true }));

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const PORT = Number(process.env.PORT || 8080);
const WSDL_PATH = path.join(__dirname, "shipping-services-api-wsdl", "ShippingAPI.V2.wsdl");

const clientInfo = {
  UserName: process.env.ARAMEX_USERNAME,
  Password: process.env.ARAMEX_PASSWORD,
  Version: "v1.0",
  AccountNumber: process.env.ARAMEX_ACCOUNT_NUMBER,
  AccountPin: process.env.ARAMEX_ACCOUNT_PIN,
  AccountEntity: process.env.ARAMEX_ACCOUNT_ENTITY,
  AccountCountryCode: process.env.ARAMEX_ACCOUNT_COUNTRY_CODE
};

async function getAramexClient() {
  const client = await soap.createClientAsync(WSDL_PATH);

  client.setEndpoint(
    (process.env.ARAMEX_ENV || "dev") === "live"
      ? "https://ws.aramex.net/shippingapi.v2/shipping/service_1_0.svc"
      : "https://ws.dev.aramex.net/shippingapi.v2/shipping/service_1_0.svc"
  );

  return client;
}

async function createShipmentAramex(data) {
  const client = await getAramexClient();

  const params = {
    ClientInfo: clientInfo,
    Transaction: {
      Reference1: data.reference || "S&R"
    },
    Shipments: {
      Shipment: [
        {
          Reference1: data.reference || "S&R",
          Reference2: "",
          Reference3: "",
          ForeignHAWB: "",
          TransportType: 0,
          ShippingDateTime: new Date(),
          DueDate: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
          Comments: data.comments || "S&R Express Shipment",
          Shipper: data.shipper,
          Consignee: data.consignee,
          ThirdParty: data.thirdParty || {},
          Details: data.details
        }
      ]
    },
    LabelInfo: {
      ReportID: 9201,
      ReportType: "URL"
    }
  };

  const [result] = await client.CreateShipmentsAsync(params);

  const shipment =
    result?.Shipments?.Shipment?.[0] ||
    result?.Shipments?.ProcessedShipment?.[0] ||
    result?.ProcessedShipments?.ProcessedShipment?.[0] ||
    null;

  return {
    tracking_number: shipment?.ID || shipment?.TrackingNumber || "",
    label_url: shipment?.ShipmentLabel?.LabelURL || "",
    raw: result
  };
}

app.get("/health", (_, res) => {
  res.json({
    ok: true,
    domain: "srxpress.com",
    env: process.env.ARAMEX_ENV || "dev"
  });
});

app.post("/webhooks/salla", async (req, res) => {
  try {
    const event = req.headers["x-salla-event"] || req.body?.event || "";
    const payload = req.body?.data || req.body || {};

    if (event === "app.store.authorize") {
      return res.status(200).json({ success: true });
    }

    if (event === "shipment.creating") {
      const order = payload;

      const shipmentData = {
        reference: `SR-${order.id || Date.now()}`,
        shipper: {
          Reference1: "S&R Express",
          AccountNumber: process.env.ARAMEX_ACCOUNT_NUMBER,
          PartyAddress: {
            Line1: "S&R Express Warehouse",
            Line2: "",
            Line3: "",
            City: "Jeddah",
            StateOrProvinceCode: "",
            PostCode: "21442",
            CountryCode: "SA"
          },
          Contact: {
            Department: "",
            PersonName: "S&R Express",
            Title: "",
            CompanyName: "S&R Express",
            PhoneNumber1: "0590050422",
            PhoneNumber1Ext: "",
            PhoneNumber2: "",
            PhoneNumber2Ext: "",
            FaxNumber: "",
            CellPhone: "0590050422",
            EmailAddress: "ops@srxpress.com",
            Type: ""
          }
        },
        consignee: {
          Reference1: String(order.id || ""),
          PartyAddress: {
            Line1:
              order?.shipping?.address?.street ||
              order?.customer_address?.street ||
              order?.address?.street ||
              "Customer Address",
            Line2: order?.shipping?.address?.district || "",
            Line3: "",
            City:
              order?.shipping?.address?.city ||
              order?.customer_address?.city ||
              order?.address?.city ||
              "Riyadh",
            StateOrProvinceCode: "",
            PostCode:
              order?.shipping?.address?.postal_code ||
              order?.customer_address?.postal_code ||
              order?.address?.postal_code ||
              "",
            CountryCode:
              order?.shipping?.address?.country_code ||
              order?.customer_address?.country_code ||
              order?.address?.country_code ||
              "SA"
          },
          Contact: {
            Department: "",
            PersonName:
              order?.customer?.name ||
              order?.customer_name ||
              "Customer",
            Title: "",
            CompanyName:
              order?.customer?.name ||
              order?.customer_name ||
              "Customer",
            PhoneNumber1:
              order?.customer?.mobile ||
              order?.customer?.phone ||
              order?.mobile ||
              "0500000000",
            PhoneNumber1Ext: "",
            PhoneNumber2: "",
            PhoneNumber2Ext: "",
            FaxNumber: "",
            CellPhone:
              order?.customer?.mobile ||
              order?.customer?.phone ||
              order?.mobile ||
              "0500000000",
            EmailAddress:
              order?.customer?.email ||
              order?.email ||
              "customer@example.com",
            Type: ""
          }
        },
        details: {
          Dimensions: {
            Length: 20,
            Width: 15,
            Height: 10,
            Unit: "CM"
          },
          ActualWeight: {
            Value: 1,
            Unit: "KG"
          },
          ChargeableWeight: {
            Value: 1,
            Unit: "KG"
          },
          DescriptionOfGoods: "Perfume",
          GoodsOriginCountry: "SA",
          NumberOfPieces: 1,
          ProductGroup: "EXP",
          ProductType: "PPX",
          PaymentType: "P",
          PaymentOptions: "ACCT",
          Services: "",
          Items: {
            ShipmentItem: [
              {
                PackageType: "Box",
                Quantity: 1,
                Weight: {
                  Value: 1,
                  Unit: "KG"
                },
                Comments: "Perfume shipment"
              }
            ]
          },
          CustomsValue: {
            Value: 100,
            CurrencyCode: "SAR"
          },
          CashOnDeliveryAmount: {
            Value: 0,
            CurrencyCode: "SAR"
          },
          InsuranceAmount: {
            Value: 0,
            CurrencyCode: "SAR"
          },
          CollectAmount: {
            Value: 0,
            CurrencyCode: "SAR"
          }
        }
      };

      const aramex = await createShipmentAramex(shipmentData);

      return res.status(200).json({
        success: true,
        data: {
          tracking_number: aramex.tracking_number,
          tracking_url: `https://srxpress.com/track?code=${encodeURIComponent(aramex.tracking_number)}`,
          label_url: aramex.label_url
        }
      });
    }

    if (event === "shipment.cancelled") {
      return res.status(200).json({ success: true });
    }

    return res.status(200).json({ success: true });
  } catch (error) {
    return res.status(500).json({
      success: false,
      message: error.message || "Webhook error"
    });
  }
});

app.get("/api/track/:trackingNumber", async (req, res) => {
  try {
    const trackingNumber = req.params.trackingNumber;

    return res.json({
      success: true,
      tracking_number: trackingNumber,
      status: "Shipment Created",
      location: "S&R Express",
      timeline: [
        {
          status: "Shipment Created",
          location: "S&R Express",
          date: new Date().toISOString()
        }
      ]
    });
  } catch (error) {
    return res.status(500).json({
      success: false,
      message: error.message || "Tracking error"
    });
  }
});

app.use(express.static(path.join(__dirname, "public")));

app.listen(PORT, () => {
  console.log(`S&R server running on port ${PORT}`);
});