import { Router, Request, Response } from "express";
import {
  requests,
  donors,
  whatsappLog,
  checkEligibility,
  STATUS_STEP,
  DonationRequest,
  WhatsappLogEntry,
} from "../lib/mockDb.js";
import { v4 as uuidv4 } from "uuid";

const router = Router();

// ─── GET /requests ────────────────────────────────────────────────────────────
router.get("/requests", (req: Request, res: Response): void => {
  let result = [...requests];
  const { status, needType } = req.query;
  if (status) result = result.filter((r) => r.status === status);
  if (needType) result = result.filter((r) => r.needType === needType);
  res.json(result);
});

// ─── GET /requests/new ───────────────────────────────────────────────────────
router.get("/requests/new", (_req: Request, res: Response): void => {
  res.json(requests.filter((r) => r.status === "new"));
});

// ─── GET /requests/published ─────────────────────────────────────────────────
router.get("/requests/published", (_req: Request, res: Response): void => {
  res.json(requests.filter((r) => r.status === "published"));
});

// ─── POST /requests ───────────────────────────────────────────────────────────
router.post("/requests", (req: Request, res: Response): void => {
  const {
    beneficiaryName,
    nationalId,
    phone,
    source,
    sourceName,
    needType,
    requestedAmount,
    description,
  } = req.body;

  if (
    !beneficiaryName ||
    !nationalId ||
    !phone ||
    !source ||
    !sourceName ||
    !needType ||
    !requestedAmount ||
    !description
  ) {
    res.status(400).json({ error: "Missing required fields" });
    return;
  }

  const { eligible } = checkEligibility(nationalId);

  let status: DonationRequest["status"];
  if (eligible === true) {
    status = "verified";
  } else if (eligible === false) {
    status = "rejected";
  } else {
    status = "pending_review";
  }

  const now = new Date().toISOString();
  const caseNum = String(requests.length + 1).padStart(3, "0");
  const newReq: DonationRequest = {
    id: uuidv4(),
    caseId: `CASE-${caseNum}`,
    beneficiaryName,
    nationalId,
    phone,
    source,
    sourceName,
    needType,
    requestedAmount: Number(requestedAmount),
    collectedAmount: 0,
    description,
    status,
    currentStep: STATUS_STEP[status],
    donorId: null,
    donorName: null,
    thankYouMessage: null,
    whatsappStatus: null,
    whatsappSentAt: null,
    rejectionReason:
      status === "rejected"
        ? "المستفيد غير مؤهل وفق قاعدة بيانات الاستحقاق"
        : null,
    createdAt: now,
    updatedAt: now,
  };

  requests.push(newReq);
  res.status(201).json(newReq);
});

// ─── GET /requests/:id ────────────────────────────────────────────────────────
router.get("/requests/:id", (req: Request, res: Response): void => {
  const item = requests.find(
    (r) => r.id === req.params.id || r.caseId === req.params.id
  );
  if (!item) {
    res.status(404).json({ error: "Not found" });
    return;
  }
  res.json(item);
});

// ─── Helper: find & update ────────────────────────────────────────────────────
function findAndUpdate(
  id: string,
  updater: (r: DonationRequest) => void,
  res: Response
): void {
  const item = requests.find((r) => r.id === id || r.caseId === id);
  if (!item) {
    res.status(404).json({ error: "Not found" });
    return;
  }
  updater(item);
  item.updatedAt = new Date().toISOString();
  res.json(item);
}

// ─── POST /requests/:id/verify ────────────────────────────────────────────────
router.post("/requests/:id/verify", (req: Request, res: Response): void => {
  findAndUpdate(
    req.params.id,
    (r) => {
      r.status = "verified";
      r.currentStep = STATUS_STEP["verified"];
    },
    res
  );
});

// ─── POST /requests/:id/publish ───────────────────────────────────────────────
router.post("/requests/:id/publish", (req: Request, res: Response): void => {
  findAndUpdate(
    req.params.id,
    (r) => {
      r.status = "published";
      r.currentStep = STATUS_STEP["published"];
    },
    res
  );
});

// ─── POST /requests/:id/donate ────────────────────────────────────────────────
router.post("/requests/:id/donate", (req: Request, res: Response): void => {
  const item = requests.find(
    (r) => r.id === req.params.id || r.caseId === req.params.id
  );
  if (!item) {
    res.status(404).json({ error: "Not found" });
    return;
  }

  const { donorName, donorPhone, donorEmail, amount } = req.body;
  if (!donorName || !donorPhone || !amount) {
    res.status(400).json({ error: "Missing donor details" });
    return;
  }

  const donorId = uuidv4();
  const existingDonor = donors.find((d) => d.phone === donorPhone);
  if (existingDonor) {
    existingDonor.totalDonated += Number(amount);
    existingDonor.donationCount += 1;
    item.donorId = existingDonor.id;
  } else {
    const newDonor = {
      id: donorId,
      name: donorName,
      phone: donorPhone,
      email: donorEmail || null,
      totalDonated: Number(amount),
      donationCount: 1,
    };
    donors.push(newDonor);
    item.donorId = donorId;
  }

  item.donorName = donorName;
  item.collectedAmount = Number(amount);
  item.status = "donated";
  item.currentStep = STATUS_STEP["donated"];
  item.updatedAt = new Date().toISOString();
  res.json(item);
});

// ─── POST /requests/:id/deliver ───────────────────────────────────────────────
router.post("/requests/:id/deliver", (req: Request, res: Response): void => {
  findAndUpdate(
    req.params.id,
    (r) => {
      r.status = "delivered";
      r.currentStep = STATUS_STEP["delivered"];
    },
    res
  );
});

// ─── POST /requests/:id/confirm-receipt ───────────────────────────────────────
router.post(
  "/requests/:id/confirm-receipt",
  (req: Request, res: Response): void => {
    findAndUpdate(
      req.params.id,
      (r) => {
        r.status = "receipt_confirmed";
        r.currentStep = STATUS_STEP["receipt_confirmed"];
      },
      res
    );
  }
);

// ─── POST /requests/:id/thank-you ─────────────────────────────────────────────
router.post("/requests/:id/thank-you", (req: Request, res: Response): void => {
  const item = requests.find(
    (r) => r.id === req.params.id || r.caseId === req.params.id
  );
  if (!item) {
    res.status(404).json({ error: "Not found" });
    return;
  }

  const { message, beneficiaryName } = req.body;
  if (!message) {
    res.status(400).json({ error: "Message is required" });
    return;
  }

  // Update beneficiary name if provided
  if (beneficiaryName) {
    item.beneficiaryName = beneficiaryName;
  }

  item.thankYouMessage = message;
  item.status = "thank_you_submitted";
  item.currentStep = STATUS_STEP["thank_you_submitted"];
  item.whatsappStatus = "pending";
  item.updatedAt = new Date().toISOString();

  // Create whatsapp log entry
  const logEntry: WhatsappLogEntry = {
    id: uuidv4(),
    caseId: item.caseId,
    donorName: item.donorName || "متبرع",
    donorPhone: donors.find((d) => d.id === item.donorId)?.phone || "",
    beneficiaryMessage: message,
    whatsappMessage: `السلام عليكم، نشكركم على تبرعكم عبر منصة إحسان.\nتم إيصال الدعم للمستفيد، وهذه رسالة الشكر من المستفيد:\n"${message}"\nرقم الحالة: ${item.caseId}`,
    status: "pending",
    sentAt: null,
    createdAt: new Date().toISOString(),
  };
  whatsappLog.push(logEntry);

  res.json(item);
});

// ─── POST /requests/:id/send-whatsapp ─────────────────────────────────────────
router.post(
  "/requests/:id/send-whatsapp",
  async (req: Request, res: Response): Promise<void> => {
    const item = requests.find(
      (r) => r.id === req.params.id || r.caseId === req.params.id
    );
    if (!item) {
      res.status(404).json({ error: "Not found" });
      return;
    }

    const simulate = process.env.OPENCLAW_SIMULATE !== "false";
    const openclawUrl = process.env.OPENCLAW_BASE_URL || "http://localhost:3100";
    const logEntry = whatsappLog.find((w) => w.caseId === item.caseId);
    const now = new Date().toISOString();

    if (simulate) {
      item.whatsappStatus = "sent";
      item.whatsappSentAt = now;
      item.status = "whatsapp_sent";
      item.currentStep = STATUS_STEP["whatsapp_sent"];
      item.updatedAt = now;
      if (logEntry) {
        logEntry.status = "sent";
        logEntry.sentAt = now;
      }
      res.json({
        success: true,
        message: "WhatsApp sent (simulated)",
        simulated: true,
        sentAt: now,
      });
      return;
    }

    // Live mode — call OpenClaw
    try {
      const donor = donors.find((d) => d.id === item.donorId);
      const payload = {
        to: donor?.phone || "",
        message: logEntry?.whatsappMessage || "",
        caseId: item.caseId,
      };

      const response = await fetch(`${openclawUrl}/api/whatsapp/send`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        throw new Error(`OpenClaw returned ${response.status}`);
      }

      item.whatsappStatus = "sent";
      item.whatsappSentAt = now;
      item.status = "whatsapp_sent";
      item.currentStep = STATUS_STEP["whatsapp_sent"];
      item.updatedAt = now;
      if (logEntry) {
        logEntry.status = "sent";
        logEntry.sentAt = now;
      }
      res.json({
        success: true,
        message: "WhatsApp sent via OpenClaw",
        simulated: false,
        sentAt: now,
      });
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : "Unknown error";
      item.whatsappStatus = "failed";
      item.updatedAt = now;
      if (logEntry) {
        logEntry.status = "failed";
      }
      res.json({
        success: false,
        message: `Failed to send via OpenClaw: ${message}`,
        simulated: false,
        sentAt: null,
      });
    }
  }
);

// ─── POST /requests/:id/close ─────────────────────────────────────────────────
router.post("/requests/:id/close", (req: Request, res: Response): void => {
  findAndUpdate(
    req.params.id,
    (r) => {
      r.status = "closed";
      r.currentStep = STATUS_STEP["closed"];
    },
    res
  );
});

// ─── POST /requests/:id/reject ────────────────────────────────────────────────
router.post("/requests/:id/reject", (req: Request, res: Response): void => {
  const item = requests.find(
    (r) => r.id === req.params.id || r.caseId === req.params.id
  );
  if (!item) {
    res.status(404).json({ error: "Not found" });
    return;
  }

  item.status = "rejected";
  item.currentStep = STATUS_STEP["rejected"];
  item.rejectionReason = req.body?.reason || "تم الرفض من قبل المشرف";
  item.updatedAt = new Date().toISOString();
  res.json(item);
});

export default router;
