import { DeleteFilled, DownOutlined } from "@ant-design/icons";
import {
  Button,
  Card,
  Col,
  Divider,
  Dropdown,
  Form,
  Input,
  InputNumber,
  Row,
  Select,
  Space,
  Statistic,
  Switch,
  Tooltip,
  Typography
} from "antd";
import Dinero from "dinero.js";
import { useTranslation } from "react-i18next";
import { useMemo, useState } from "react";
import i18n from "../../translations/i18n";
import dayjs from "../../utils/day";
import DmsCdkMakes from "../dms-cdk-makes/dms-cdk-makes.component";
import DmsCdkMakesRefetch from "../dms-cdk-makes/dms-cdk-makes.refetch.component";
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import { DMS_MAP } from "../../utils/dmsUtils";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";

/**
 * CDK-like DMS post form:
 *  - CDK / Fortellis / PBS
 *  - CDK vehicle details + make/model selection
 *  - Payer list with discrepancy gating
 *  - Submit: "{mode}-export-job"
 * @param bodyshop
 * @param socket
 * @param job
 * @param logsRef
 * @param mode
 * @param allocationsSummary
 * @returns {JSX.Element}
 * @constructor
 */
export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode, allocationsSummary }) {
  const [form] = Form.useForm();
  const { t } = useTranslation();
  const [, /*unused*/ setTick] = useState(0); // handy if you need a forceUpdate later

  const {
    treatments: { Fortellis }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Fortellis"],
    splitKey: bodyshop.imexshopid
  });

  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`
      ),
      journal: bodyshop.cdk_configuration?.default_journal
    }),
    [job, bodyshop, t]
  );

  // Payers helpers
  const handlePayerSelect = (value, index) => {
    form.setFieldsValue({
      payers: (form.getFieldValue("payers") || []).map((payer, mapIndex) => {
        if (index !== mapIndex) return payer;
        const cdkPayer =
          bodyshop.cdk_configuration.payers && bodyshop.cdk_configuration.payers.find((i) => i.name === value);
        if (!cdkPayer) return payer;
        return {
          ...cdkPayer,
          dms_acctnumber: cdkPayer.dms_acctnumber,
          controlnumber: job?.[cdkPayer.control_type]
        };
      })
    });
    setTick((n) => n + 1);
  };

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

    if (mode === DMS_MAP.fortellis) {
      socket.emit("fortellis-export-job", {
        jobid: job.id,
        txEnvelope: { ...values, SubscriptionID: bodyshop.cdk_dealerid }
      });
    } else {
      socket.emit(`${mode}-export-job`, { jobid: job.id, txEnvelope: values });
    }

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

  // Totals & discrepancy
  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]);

  return (
    <Card title={t("jobs.labels.dms.postingform")}>
      <Form
        form={form}
        layout="vertical"
        onFinish={handleFinish}
        style={{ width: "100%" }}
        initialValues={initialValues}
      >
        {/* TOP ROW */}
        <Row gutter={[16, 12]} align="bottom">
          <Col xs={24} sm={12} md={8} lg={6}>
            <Form.Item name="journal" label={t("jobs.fields.dms.journal")} rules={[{ required: true }]}>
              <Input />
            </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>

        {/* CDK vehicle details (kept for CDK/Fortellis paths when dealer id exists) */}
        {bodyshop.cdk_dealerid && (
          <>
            <Row gutter={[16, 12]}>
              <Col xs={24} sm={12} md={8}>
                <Form.Item name="dms_make" label={t("jobs.fields.dms.dms_make")} rules={[{ required: true }]}>
                  <Input disabled />
                </Form.Item>
              </Col>
              <Col xs={24} sm={12} md={8}>
                <Form.Item name="dms_model" label={t("jobs.fields.dms.dms_model")} rules={[{ required: true }]}>
                  <Input disabled />
                </Form.Item>
              </Col>
              <Col xs={24} sm={12} md={8}>
                <Form.Item name="inservicedate" label={t("jobs.fields.dms.inservicedate")}>
                  <DateTimePicker isDateOnly />
                </Form.Item>
              </Col>
            </Row>

            <Row gutter={[16, 12]} align="middle">
              <Col>
                <DmsCdkMakes form={form} job={job} />
              </Col>
              <Col>
                <DmsCdkMakesRefetch />
              </Col>
              <Col>
                <Form.Item name="dms_unsold" label={t("jobs.fields.dms.dms_unsold")} initialValue={false}>
                  <Switch />
                </Form.Item>
              </Col>
              <Col>
                <Form.Item
                  name="dms_model_override"
                  label={t("jobs.fields.dms.dms_model_override")}
                  initialValue={false}
                >
                  <Switch />
                </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={Fortellis.treatment === "on" ? 40 : 240} showCount />
            </Form.Item>
          </Col>
        </Row>

        <Divider />

        {/* Totals */}
        <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>

        {/* Payers list */}
        <Divider />
        <Form.List name={["payers"]}>
          {(fields, { add, remove }) => (
            <div>
              {fields.map((field, index) => (
                <Card
                  key={field.key}
                  size="small"
                  style={{ marginBottom: 12 }}
                  title={`${t("jobs.fields.dms.payer.payer_type")} #${index + 1}`}
                  extra={
                    <Tooltip title={t("general.actions.remove", "Remove")}>
                      <Button
                        type="text"
                        danger
                        icon={<DeleteFilled />}
                        aria-label={t("general.actions.remove", "Remove")}
                        onClick={() => remove(field.name)}
                      />
                    </Tooltip>
                  }
                >
                  <Row gutter={[16, 8]} align="middle">
                    <Col xs={24} sm={12} md={8} lg={6}>
                      <Form.Item
                        label={t("jobs.fields.dms.payer.name")}
                        name={[field.name, "name"]}
                        rules={[{ required: true }]}
                      >
                        <Select
                          showSearch={{
                            optionFilterProp: "label",
                            filterOption: (input, option) => option.label.toLowerCase().includes(input.toLowerCase())
                          }}
                          style={{ width: "100%" }}
                          onSelect={(value) => handlePayerSelect(value, index)}
                          options={bodyshop.cdk_configuration?.payers?.map((payer) => ({
                            key: payer.name,
                            value: payer.name,
                            label: payer.name
                          }))}
                        />
                      </Form.Item>
                    </Col>

                    <Col xs={24} sm={12} md={8} lg={6}>
                      <Form.Item
                        label={t("jobs.fields.dms.payer.dms_acctnumber")}
                        name={[field.name, "dms_acctnumber"]}
                        rules={[{ required: true }]}
                      >
                        <Input disabled />
                      </Form.Item>
                    </Col>

                    <Col xs={24} sm={12} md={8} lg={5}>
                      <Form.Item
                        label={t("jobs.fields.dms.payer.amount")}
                        name={[field.name, "amount"]}
                        rules={[{ required: true }]}
                      >
                        <CurrencyInput min={0} />
                      </Form.Item>
                    </Col>

                    <Col xs={24} sm={12} md={10} lg={7}>
                      <Form.Item
                        label={
                          <div>
                            {t("jobs.fields.dms.payer.controlnumber")}{" "}
                            <Dropdown
                              trigger={["click"]}
                              menu={{
                                items:
                                  bodyshop.cdk_configuration.controllist?.map((key, idx) => ({
                                    key: idx,
                                    label: key.name,
                                    onClick: () => {
                                      form.setFieldsValue({
                                        payers: (form.getFieldValue("payers") || []).map((row, mapIndex) => {
                                          if (index !== mapIndex) return row;
                                          return { ...row, controlnumber: key.controlnumber };
                                        })
                                      });
                                    }
                                  })) ?? []
                              }}
                            >
                              <a href="#" onClick={(e) => e.preventDefault()}>
                                <DownOutlined />
                              </a>
                            </Dropdown>
                          </div>
                        }
                        name={[field.name, "controlnumber"]}
                        rules={[{ required: true }]}
                      >
                        <Input />
                      </Form.Item>
                    </Col>

                    <Col xs={24}>
                      <Form.Item shouldUpdate noStyle>
                        {() => {
                          const payers = form.getFieldValue("payers");
                          const row = payers?.[index];
                          const cdkPayer =
                            bodyshop.cdk_configuration.payers &&
                            bodyshop.cdk_configuration.payers.find((i) => i && row && i.name === row.name);
                          if (i18n.exists(`jobs.fields.${cdkPayer?.control_type}`))
                            return <div>{cdkPayer && t(`jobs.fields.${cdkPayer?.control_type}`)}</div>;
                          else if (i18n.exists(`jobs.fields.dms.control_type.${cdkPayer?.control_type}`)) {
                            return <div>{cdkPayer && t(`jobs.fields.dms.control_type.${cdkPayer?.control_type}`)}</div>;
                          } else {
                            return null;
                          }
                        }}
                      </Form.Item>
                    </Col>
                  </Row>
                </Card>
              ))}
              <Form.Item>
                <Button
                  disabled={!(fields.length < 3)}
                  onClick={() => {
                    if (fields.length < 3) add();
                  }}
                  style={{ width: "100%" }}
                >
                  {t("jobs.actions.dms.addpayer")}
                </Button>
              </Form.Item>
            </div>
          )}
        </Form.List>

        {/* Validation gates & summary */}
        <Form.Item shouldUpdate>
          {() => {
            let totalAllocated = Dinero();
            const payers = form.getFieldValue("payers") || [];
            payers.forEach((payer) => {
              totalAllocated = totalAllocated.add(Dinero({ amount: Math.round((payer?.amount || 0) * 100) }));
            });

            const discrep = totals ? totals.totalSale.subtract(totalAllocated) : Dinero();

            // gate: must have payers filled + zero discrepancy when we have a summary
            const payersOk =
              payers.length > 0 &&
              payers.every((p) => p?.name && p.dms_acctnumber && (p.amount ?? "") !== "" && p.controlnumber);

            const hasAllocations = allocationsSummary && allocationsSummary.length > 0;
            const nonRrDiscrepancyGate = hasAllocations ? discrep.getAmount() !== 0 : true;

            const disablePost = !payersOk || nonRrDiscrepancyGate;

            return (
              <Space size="large" wrap align="center">
                <Statistic
                  title={t("jobs.labels.subtotal")}
                  value={(totals ? totals.totalSale : Dinero()).toFormat()}
                />
                <Typography.Title>-</Typography.Title>
                <Statistic title={t("jobs.labels.dms.totalallocated")} value={totalAllocated.toFormat()} />
                <Typography.Title>=</Typography.Title>
                <Statistic
                  title={t("jobs.labels.dms.notallocated")}
                  styles={{ content: { color: discrep.getAmount() === 0 ? "green" : "red" } }}
                  value={discrep.toFormat()}
                />
                <Button disabled={disablePost} htmlType="submit">
                  {t("jobs.actions.dms.post")}
                </Button>
              </Space>
            );
          }}
        </Form.Item>
      </Form>
    </Card>
  );
}
