import { ReloadOutlined, RollbackOutlined } from "@ant-design/icons";
import {
  Button,
  Card,
  Col,
  Divider,
  Form,
  Input,
  InputNumber,
  Row,
  Select,
  Space,
  Statistic,
  Tooltip,
  Typography
} from "antd";
import Dinero from "dinero.js";
import { useTranslation } from "react-i18next";
import { useEffect, useMemo, useState } from "react";
import dayjs from "../../utils/day";

/**
 * RR DMS Post Form component
 * Submit: "rr-export-job"
 * @param bodyshop
 * @param socket
 * @param job
 * @param logsRef
 * @param allocationsSummary
 * @param opCodeParts          // { prefix, base, suffix } from container
 * @param onChangeOpCodeParts  // (partsWithFlags) => void
 * @returns {JSX.Element}
 * @constructor
 */
export default function RRPostForm({
  bodyshop,
  socket,
  job,
  logsRef,
  allocationsSummary,
  opCodeParts,
  onChangeOpCodeParts
}) {
  const [form] = Form.useForm();
  const { t } = useTranslation();

  // Capture the baseline/default OpCode parts ONCE per mount (tied to resetKey in container)
  const [baselineOpCodeParts] = useState(() => ({
    prefix: opCodeParts?.prefix ?? "",
    base: opCodeParts?.base ?? "",
    suffix: opCodeParts?.suffix ?? ""
  }));

  // Advisors
  const [advisors, setAdvisors] = useState([]);
  const [advLoading, setAdvLoading] = useState(false);

  const getAdvisorNumber = (a) => a?.advisorId;
  const getAdvisorLabel = (a) => `${a?.firstName || ""} ${a?.lastName || ""}`.trim();

  const fetchRrAdvisors = (refresh = false) => {
    if (!socket) return;
    setAdvLoading(true);

    const onResult = (payload) => {
      try {
        const list = payload?.result ?? payload ?? [];
        setAdvisors(Array.isArray(list) ? list : []);
      } finally {
        setAdvLoading(false);
        socket.off("rr-get-advisors:result", onResult);
      }
    };

    socket.once("rr-get-advisors:result", onResult);
    socket.emit("rr-get-advisors", { departmentType: "B", refresh }, (ack) => {
      if (ack?.ok) {
        const list = ack.result ?? [];
        setAdvisors(Array.isArray(list) ? list : []);
      } else if (ack) {
        console.error("Something went wrong fetching DMS Advisors");
      }
      setAdvLoading(false);
      socket.off("rr-get-advisors:result", onResult);
    });
  };

  useEffect(() => {
    fetchRrAdvisors(false);
  }, [bodyshop?.id, socket]);

  const initialValues = useMemo(
    () => ({
      story: `${t("jobs.labels.dms.defaultstory", {
        ro_number: job.ro_number,
        ownr_nm: `${job.ownr_fn || ""} ${job.ownr_ln || ""} ${job.ownr_co_nm || ""}`.trim(),
        ins_co_nm: job.ins_co_nm || "N/A",
        clm_po: `${job.clm_no ? `${job.clm_no} ` : ""}${job.po_number || ""}`
      }).trim()}.${
        job.area_of_damage?.impact1
          ? " " +
            t("jobs.labels.dms.damageto", {
              area_of_damage: (job.area_of_damage && job.area_of_damage.impact1.padStart(2, "0")) || "UNKNOWN"
            })
          : ""
      }`.slice(0, 239),
      inservicedate: dayjs(
        `${
          (job.v_model_yr &&
            (job.v_model_yr < 100
              ? job.v_model_yr >= (dayjs().year() + 1) % 100
                ? 1900 + parseInt(job.v_model_yr, 10)
                : 2000 + parseInt(job.v_model_yr, 10)
              : job.v_model_yr)) ||
          2019
        }-01-01`
      ),
      opPrefix: opCodeParts?.prefix ?? "",
      opBase: opCodeParts?.base ?? "",
      opSuffix: opCodeParts?.suffix ?? ""
    }),
    [job, t, opCodeParts]
  );

  // Keep the RR OpCode parts in sync with DmsContainer state
  const opPrefixWatch = Form.useWatch("opPrefix", form);
  const opBaseWatch = Form.useWatch("opBase", form);
  const opSuffixWatch = Form.useWatch("opSuffix", form);

  // Detect if current form values differ from baseline defaults
  const isCustomOpCode = useMemo(() => {
    const current = {
      prefix: opPrefixWatch !== undefined ? opPrefixWatch : (baselineOpCodeParts.prefix ?? ""),
      base: opBaseWatch !== undefined ? opBaseWatch : (baselineOpCodeParts.base ?? ""),
      suffix: opSuffixWatch !== undefined ? opSuffixWatch : (baselineOpCodeParts.suffix ?? "")
    };

    return (
      current.prefix !== (baselineOpCodeParts.prefix ?? "") ||
      current.base !== (baselineOpCodeParts.base ?? "") ||
      current.suffix !== (baselineOpCodeParts.suffix ?? "")
    );
  }, [opPrefixWatch, opBaseWatch, opSuffixWatch, baselineOpCodeParts]);

  // Push changes up to container with some metadata
  useEffect(() => {
    if (!onChangeOpCodeParts) return;

    const parts = {
      prefix: opPrefixWatch || "",
      base: opBaseWatch || "",
      suffix: opSuffixWatch || "",
      isCustom: isCustomOpCode
    };

    onChangeOpCodeParts(parts);
  }, [opPrefixWatch, opBaseWatch, opSuffixWatch, isCustomOpCode, onChangeOpCodeParts]);

  const handleFinish = (values) => {
    if (!socket) return;

    const { opPrefix, opBase, opSuffix, ...rest } = values;

    const combinedOpCode = `${opPrefix || ""}${opBase || ""}${opSuffix || ""}`.trim();

    const txEnvelope = {
      ...rest,
      opPrefix,
      opBase,
      opSuffix
    };

    if (combinedOpCode) {
      txEnvelope.opCode = combinedOpCode;
    }

    socket.emit("rr-export-job", {
      bodyshopId: bodyshop?.id,
      jobId: job.id,
      job,
      txEnvelope
    });

    logsRef?.current?.scrollIntoView({ behavior: "smooth" });
  };

  // Discrepancy is ignored for RR; we still show totals for operator context.
  // Use the lifted allocationsSummary from the container instead of reading from the socket.
  const totals = useMemo(() => {
    if (!allocationsSummary || allocationsSummary.length === 0) {
      return { totalSale: Dinero(), totalCost: Dinero() };
    }

    return allocationsSummary.reduce(
      (acc, val) => ({
        totalSale: acc.totalSale.add(Dinero(val.sale)),
        totalCost: acc.totalCost.add(Dinero(val.cost))
      }),
      { totalSale: Dinero(), totalCost: Dinero() }
    );
  }, [allocationsSummary]);

  const handleResetOpCode = () => {
    form.setFieldsValue({
      opPrefix: baselineOpCodeParts.prefix,
      opBase: baselineOpCodeParts.base,
      opSuffix: baselineOpCodeParts.suffix
    });
  };

  // Check if early RO was created (job has all early RO fields)
  const hasEarlyRO = !!(job?.dms_id && job?.dms_customer_id && job?.dms_advisor_id);

  return (
    <Card title={t("jobs.labels.dms.postingform")}>
      {hasEarlyRO && (
        <Typography.Paragraph type="success" strong style={{ marginBottom: 16 }}>
          ✅ {t("jobs.labels.dms.earlyro.created")} {job.dms_id}
          <br />
          <Typography.Text type="secondary">{t("jobs.labels.dms.earlyro.willupdate")}</Typography.Text>
        </Typography.Paragraph>
      )}
      <Form
        form={form}
        layout="vertical"
        onFinish={handleFinish}
        style={{ width: "100%" }}
        initialValues={initialValues}
      >
        <Row gutter={[16, 12]} align="bottom">
          {/* Advisor + inline Refresh - Only show if no early RO */}
          {!hasEarlyRO && (
            <Col xs={24} sm={24} md={12} lg={8}>
              <Form.Item label={t("jobs.fields.dms.advisor")} required>
                <Space.Compact block>
                  <Form.Item
                    name="advisorNo"
                    noStyle
                    rules={[{ required: true, message: t("general.validation.required") }]}
                  >
                    <Select
                      style={{ flex: 1 }}
                      loading={advLoading}
                      allowClear
                      placeholder={t("general.actions.select", "Select...")}
                      popupMatchSelectWidth
                      options={advisors
                        .map((a) => {
                          const value = getAdvisorNumber(a);
                          if (value == null) return null;
                          return { value: String(value), label: getAdvisorLabel(a) || String(value) };
                        })
                        .filter(Boolean)}
                      notFoundContent={advLoading ? t("general.labels.loading") : t("general.labels.none")}
                    />
                  </Form.Item>
                  <Tooltip title={t("general.actions.refresh")}>
                    <Button
                      aria-label={t("general.actions.refresh")}
                      icon={<ReloadOutlined />}
                      onClick={() => fetchRrAdvisors(true)}
                      loading={advLoading}
                    />
                  </Tooltip>
                </Space.Compact>
              </Form.Item>
            </Col>
          )}

          {/* RR OpCode (prefix / base / suffix) - Only show if no early RO */}
          {!hasEarlyRO && (
            <Col xs={24} sm={12} md={12} lg={8}>
              <Form.Item
                required
                label={
                  <Space size="small" align="center">
                    {t("jobs.fields.dms.rr_opcode", "RR OpCode")}
                    {isCustomOpCode && (
                      <Button
                        type="link"
                        size="small"
                        icon={<RollbackOutlined />}
                        onClick={handleResetOpCode}
                        style={{ padding: 0 }}
                      >
                        {t("jobs.fields.dms.rr_opcode_reset", "Reset")}
                      </Button>
                    )}
                  </Space>
                }
              >
                <Space.Compact block>
                  <Form.Item name="opPrefix" noStyle>
                    <Input
                      allowClear
                      maxLength={4}
                      style={{ width: "30%" }}
                      placeholder={t("jobs.fields.dms.rr_opcode_prefix", "Prefix")}
                    />
                  </Form.Item>
                  <Form.Item name="opBase" noStyle rules={[{ required: true }]}>
                    <Input
                      allowClear
                      maxLength={10}
                      style={{ width: "40%" }}
                      placeholder={t("jobs.fields.dms.rr_opcode_base", "Base")}
                    />
                  </Form.Item>
                  <Form.Item name="opSuffix" noStyle>
                    <Input
                      allowClear
                      maxLength={4}
                      style={{ width: "30%" }}
                      placeholder={t("jobs.fields.dms.rr_opcode_suffix", "Suffix")}
                    />
                  </Form.Item>
                </Space.Compact>
              </Form.Item>
            </Col>
          )}

          <Col xs={12} sm={8} md={6} lg={4}>
            <Form.Item name="kmin" label={t("jobs.fields.kmin")} initialValue={job?.kmin} rules={[{ required: true }]}>
              <InputNumber style={{ width: "100%" }} disabled />
            </Form.Item>
          </Col>

          <Col xs={12} sm={8} md={6} lg={4}>
            <Form.Item
              name="kmout"
              label={t("jobs.fields.kmout")}
              initialValue={job?.kmout}
              rules={[{ required: true }]}
            >
              <InputNumber style={{ width: "100%" }} disabled />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={[16, 12]}>
          <Col span={24}>
            <Form.Item name="story" label={t("jobs.fields.dms.story")} rules={[{ required: true }]}>
              <Input.TextArea maxLength={240} />
            </Form.Item>
          </Col>
        </Row>

        <Divider />

        <Space size="large" wrap align="center" style={{ marginBottom: 16 }}>
          <Statistic
            title={t("jobs.fields.ded_amt")}
            value={Dinero(job.job_totals.totals.custPayable.deductible).toFormat()}
          />
          <Statistic
            title={t("jobs.labels.total_cust_payable")}
            value={Dinero(job.job_totals.totals.custPayable.total).toFormat()}
          />
          <Statistic
            title={t("jobs.labels.net_repairs")}
            value={Dinero(job.job_totals.totals.net_repairs).toFormat()}
          />
        </Space>

        {/* Validation  */}
        <Form.Item shouldUpdate>
          {() => {
            // When early RO exists, advisor is already set, so we don't need to validate it
            const advisorOk = hasEarlyRO ? true : !!form.getFieldValue("advisorNo");
            return (
              <Space size="large" wrap align="center">
                <Statistic title={t("jobs.labels.subtotal")} value={totals.totalSale.toFormat()} />
                <Typography.Title>=</Typography.Title>
                <Button disabled={!advisorOk} htmlType="submit" type={hasEarlyRO ? "default" : "primary"}>
                  {hasEarlyRO ? t("jobs.actions.dms.update_ro") : t("jobs.actions.dms.post")}
                </Button>
              </Space>
            );
          }}
        </Form.Item>
      </Form>
    </Card>
  );
}
