import { useEffect, useState } from "react";
import Dashboard from "../../pages/Dashboard/Dashboard";
import Select from "react-select";
import { useLocation, useNavigate } from "react-router-dom";

import {
  customStylesAccUser,
  firstCharUpperCase,
  selectThemeUser,
} from "../../Utils/common";

import {
  getMonthYearOptions,
  hotelTouristMonthlySection,
  parseJSONSafe,
  validateFormData,
  validateTableFields,
} from "./visitorTrackingUtils";
import {
  editUserVistingTrackingData,
  getHotelDistrict,
  getStates,
} from "../../services/api/user";
import { useLanguage } from "../LanguageProvider/LanguageProvider ";
import { Message } from "../message";
import { getCountryOptions } from "../../Utils/locationOptions";

/* ================= UTILS ================= */

const sumColumn = (rows = [], key) => {
  if (!Array.isArray(rows)) return "";
  let total = 0;
  let hasValue = false;

  rows.forEach((row) => {
    const val = Number(row?.[key]);
    if (!isNaN(val)) {
      total += val;
      hasValue = true;
    }
  });

  return hasValue ? total : "";
};

const preventInvalidNumberKeys = (e) => {
  if (["-", "e", "E", "+"].includes(e.key)) {
    e.preventDefault();
  }
};

const parseMonthYear = (value) => {
  if (!value) return {};
  const [month, year] = value.split(",");
  return {
    report_month: Number(month),
    report_year: Number(year),
  };
};

/* ================= COMPONENT ================= */

const EditVisitorTracking = () => {
  const { language } = useLanguage();
  const navigate = useNavigate();
  const { state } = useLocation();

  const isEditMode = !!state?.rowData;
  const [formData, setFormData] = useState({});
  const [errors, setErrors] = useState({});
  const [districtId, setDistrictId] = useState(null);
  const [categoryId, setCategoryId] = useState(null);
  const [usedMonths, setUsedMonths] = useState([]);
  const [apiMessage, setApiMessage] = useState({ type: "", message: "" });
  const [stateOptions, setStateOptions] = useState([]);
  const [countryOptions, setCountryOptions] = useState([]);

  /* ================= INIT ================= */

  // EDIT MODE INIT
  useEffect(() => {
    if (!isEditMode) return;

    const indianRows = parseJSONSafe(state.rowData.indian_tourist_details);
    const foreignerRows = parseJSONSafe(
      state.rowData.foreigner_tourist_details
    );

    setDistrictId(state.rowData.district_id);
    setCategoryId(state.rowData.category_id);

    setFormData({
      ...state.rowData,
      report_month_year: `${state.rowData.report_month},${state.rowData.report_year}`,
      indian_tourist_details: indianRows,
      foreigner_tourist_details: foreignerRows,
      monthy_total_tourists_indian: sumColumn(indianRows, "number_of_tourists"),
      monthy_nghts_spent_indian: sumColumn(indianRows, "bed_nights_spent"),
      monthy_total_tourists_foreigner: sumColumn(
        foreignerRows,
        "number_of_tourists"
      ),
      monthy_nghts_spent_foreigner: sumColumn(
        foreignerRows,
        "bed_nights_spent"
      ),
    });
  }, [isEditMode]);

  // CREATE MODE → FETCH DISTRICT
  useEffect(() => {
    if (isEditMode) return;

    const fetchDistrict = async () => {
      try {
        const res = await getHotelDistrict();
        setDistrictId(res.data?.district_id || null);
        setCategoryId(res.data?.category_id || null);
        setUsedMonths(res.data?.used_months || []);
      } catch {
        setDistrictId(null);
      }
    };

    fetchDistrict();
  }, [isEditMode]);

  useEffect(() => {
    const loadLocationData = async () => {
      try {
        /* INDIAN STATES */
        const res = await getStates();
        const states =
          res?.data?.map((s) => ({
            label: language ? s.name_hi : s.name_en,
            value: s.name_en,
          })) || [];

        setStateOptions(states);

        /* COUNTRIES */
        setCountryOptions(getCountryOptions(language));
      } catch {
        setStateOptions([]);
        setCountryOptions([]);
      }
    };

    loadLocationData();
  }, [language]);

  /* ================= FORM HANDLERS ================= */

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((p) => ({ ...p, [name]: value }));
    setErrors((p) => ({ ...p, [name]: null }));
  };

  const handleInputChange = (tableName, rows, e, rowIndex, fieldName) => {
    const updatedRows = [...rows];
    updatedRows[rowIndex] = {
      ...updatedRows[rowIndex],
      [fieldName]: e.target.value,
    };

    handleTableChange(tableName, updatedRows, rowIndex, fieldName);
  };

  const addRow = (tableName, rows, headers) => {
    const newRow = {};
    headers.forEach((h) => (newRow[h.name] = ""));
    handleTableChange(tableName, [...rows, newRow], true);
  };

  const removeRow = (tableName, rows, rowIndex) => {
    const updatedRows = rows.filter((_, i) => i !== rowIndex);
    handleTableChange(tableName, updatedRows);
  };

  const handleTableChange = (
    tableName,
    rows,
    changedRowIndex = null,
    changedField = null
  ) => {
    setFormData((prev) => {
      const updated = { ...prev, [tableName]: rows };

      // Recalculate totals for Indian tourist details
      if (tableName === "indian_tourist_details") {
        updated.monthy_total_tourists_indian = sumColumn(
          rows,
          "number_of_tourists"
        );
        updated.monthy_nghts_spent_indian = sumColumn(rows, "bed_nights_spent");
      }

      // Recalculate totals for Foreigner tourist details
      if (tableName === "foreigner_tourist_details") {
        updated.monthy_total_tourists_foreigner = sumColumn(
          rows,
          "number_of_tourists"
        );
        updated.monthy_nghts_spent_foreigner = sumColumn(
          rows,
          "bed_nights_spent"
        );
      }

      return updated;
    });

    setErrors((prevErrors) => {
      let updatedErrors = { ...prevErrors };

      // Remove error for the changed field
      if (changedRowIndex !== null && changedField) {
        const key = `${tableName}.${changedRowIndex}.${changedField}`;
        if (updatedErrors[key]) delete updatedErrors[key];
      }

      // Remove errors for totals if table changed
      if (tableName === "indian_tourist_details") {
        delete updatedErrors["monthy_total_tourists_indian"];
        delete updatedErrors["monthy_nghts_spent_indian"];
      } else if (tableName === "foreigner_tourist_details") {
        delete updatedErrors["monthy_total_tourists_foreigner"];
        delete updatedErrors["monthy_nghts_spent_foreigner"];
      }

      // Re-index errors if a row was removed
      if (
        rows.length <
        Object.keys(prevErrors).filter((k) => k.startsWith(tableName)).length
      ) {
        const newErrors = {};
        Object.keys(updatedErrors).forEach((errKey) => {
          const parts = errKey.split(".");
          if (parts[0] === tableName) {
            const rowIdx = parseInt(parts[1], 10);
            const field = parts[2];
            if (rowIdx >= rows.length) return; // skip removed row
            newErrors[`${tableName}.${rowIdx}.${field}`] =
              updatedErrors[errKey];
          } else {
            newErrors[errKey] = updatedErrors[errKey];
          }
        });
        updatedErrors = newErrors;
      }

      return updatedErrors;
    });
  };

  /* ================= SUBMIT ================= */

  const handleSubmit = async () => {
    let newErrors = {};

    // Check report month
    if (!formData.report_month_year) {
      newErrors.report_month_year = {
        hi: "रिपोर्ट माह आवश्यक है",
        en: "Report month is required",
      };
    }

    const { errors: stepErrors } = validateFormData(
      hotelTouristMonthlySection,
      formData
    );

    const { errors: tableErrors, isValid } = validateTableFields(
      hotelTouristMonthlySection,
      formData
    );

    const allErrors = { ...newErrors, ...stepErrors, ...tableErrors };
    setErrors(allErrors);

    if (Object.keys(allErrors).length || !isValid) return;

    const { report_month, report_year } = parseMonthYear(
      formData.report_month_year
    );

    const payload = {
      category_id: categoryId,
      district_id: districtId,
      report_month,
      report_year,

      monthy_total_tourists_indian: formData.monthy_total_tourists_indian || 0,
      monthy_nghts_spent_indian: formData.monthy_nghts_spent_indian || 0,
      monthy_total_tourists_foreigner:
        formData.monthy_total_tourists_foreigner || 0,
      monthy_nghts_spent_foreigner: formData.monthy_nghts_spent_foreigner || 0,

      indian_tourist_details: JSON.stringify(
        formData.indian_tourist_details || []
      ),
      foreigner_tourist_details: JSON.stringify(
        formData.foreigner_tourist_details || []
      ),
    };

    try {
      const response = await editUserVistingTrackingData(payload);
      if (response.status === 200) {
        navigate("/visitor-tracking", {
          state: {
            message: language
              ? "डेटा सफलतापूर्वक सहेजा गया"
              : "Data saved successfully",
          },
        });
      } else {
        setApiMessage({
          type: "error",
          message: language
            ? "ट्रैकिंग सबमिट करने में असमर्थ, कृपया बाद में प्रयास करें"
            : "Unable to submit the tracking, please try later",
        });
      }
    } catch (err) {
      setApiMessage({ type: "error", message: err?.message });
    }
  };

  const filteredMonthOptions = isEditMode
    ? getMonthYearOptions(language)
    : getMonthYearOptions(language).filter((opt) => !usedMonths.includes(opt.value));

  const getFilteredOptions = (allOptions, rows, currentRowIndex, fieldName) => {
    // Collect all selected values except the current row
    const usedValues = rows
      .filter((_, i) => i !== currentRowIndex)
      .map((r) => r[fieldName])
      .filter(Boolean); // remove empty/null

    // Mark already used options as disabled
    return allOptions.map((opt) => ({
      ...opt,
      isDisabled: usedValues.includes(opt.value),
    }));
  };

  return (
    <Dashboard
      first={language ? "विज़िटर ट्रैकिंग" : "Visitor Tracking"}
      second={
        language ? "विज़िटर ट्रैकिंग संपादित करें" : "Edit Visitor Tracking"
      }
      head={
        language ? "विज़िटर ट्रैकिंग संपादित करें" : "Edit Visitor Tracking"
      }
    >
      {apiMessage && (
        <Message
          apiMessage={apiMessage}
          setApiMessage={setApiMessage}
        ></Message>
      )}
      <div className="aod-bottom">
        <div className="page_heading d-flex justify-content-between align-items-center">
          <h5>
            {language
              ? "विज़िटर ट्रैकिंग संपादित करें"
              : "Edit Visitor Tracking"}
          </h5>

          <button
            type="button"
            onClick={() => navigate("/visitor-tracking")}
            style={{
              marginTop: "8px",
              padding: "8px 12px",
              backgroundColor: "#00684a",
              color: "#ffffff",
              fontSize: "0.875rem",
              borderRadius: "6px",
              border: "none",
              cursor: "pointer",
              textAlign: "right",
            }}
          >
            {language ? "पीछे" : "Back"}
          </button>
        </div>
        <div className="col-md-4 mb-3">
          <div
            className="f_fields"
            style={{
              display: "flex",
              alignItems: "center",
              gap: "12px",
            }}
          >
            {/* LABEL */}
            <label
              className="form-label mb-0"
              style={{
                whiteSpace: "nowrap",
                minWidth: "110px",
              }}
            >
              <span className="field-label">
                {language ? "रिपोर्ट माह" : "Report Month"}
              </span>
            </label>

            {/* SELECT */}
            <div style={{ flex: 1 }}>
              <Select
                value={getMonthYearOptions(language).find(
                  (o) =>
                    o.value ===
                    `${formData.report_month},${formData.report_year}`
                )}
                options={filteredMonthOptions}
                isDisabled={isEditMode}
                onChange={(opt) =>
                  setFormData((p) => ({
                    ...p,
                    report_month_year: opt?.value || "",
                  }))
                }
                styles={customStylesAccUser}
                theme={selectThemeUser}
                placeholder={language ? "माह चुनें" : "Select Month"}
              />
              {errors["report_month_year"] && (
                <p
                  style={{
                    color: "#ef4444",
                    fontSize: "0.75rem",
                    marginTop: "4px",
                  }}
                >
                  {language
                    ? errors["report_month_year"].hi
                    : errors["report_month_year"].en}
                </p>
              )}
            </div>
          </div>
        </div>
        {hotelTouristMonthlySection.map((section, sectionIndex) => {
          const updatedSection = {
            ...section,
            fields: section.fields.map((field) => {
              if (field.inputProps?.type !== "table") return field;

              return {
                ...field,
                inputProps: {
                  ...field.inputProps,
                  headers: field.inputProps.headers.map((header) => {
                    if (header.name === "state") {
                      return { ...header, options: stateOptions };
                    }
                    if (header.name === "country") {
                      return { ...header, options: countryOptions };
                    }
                    return header;
                  }),
                },
              };
            }),
          };
          return (
            <div key={sectionIndex}>
              {/* ===== SECTION TITLE ===== */}
              <div className="m-wrapper-heading">
                <div>
                  {language
                    ? section.title?.hi
                    : firstCharUpperCase(section.title?.en)}
                </div>
              </div>

              <div className="m-form-wrapper">
                <div className="row">
                  {updatedSection.fields.map((field, fieldIndex) => {
                    const { label, htmlFor, inputProps } = field;
                    const { placeholder, options, type, validation } =
                      inputProps;
                    const value = formData?.[inputProps?.name];
                    /* ================= TABLE TYPE ================= */
                    if (type === "table") {
                      const { headers } = inputProps;
                      const tableName = inputProps.name;

                      let currentRows = formData[tableName] || [];

                      if (typeof currentRows === "string") {
                        try {
                          const parsed = JSON.parse(currentRows);
                          currentRows = Array.isArray(parsed) ? parsed : [];
                        } catch (e) {
                          currentRows = [];
                        }
                      }

                      const rows =
                        currentRows.length > 0
                          ? currentRows
                          : field.inputProps.rows || [];

                      return (
                        <div className="col-lg-12 mb-4" key={fieldIndex}>
                          <div className="table-responsive">
                            <table
                              style={{
                                width: "100%",
                                borderCollapse: "collapse",
                                border: "1px solid #9ca3af",
                              }}
                            >
                              <thead style={{ background: "#e5f5f4" }}>
                                <tr>
                                  <th
                                    style={{
                                      border: "1px solid #9ca3af",
                                      padding: "8px",
                                      textAlign: "center",
                                      fontSize: "0.875rem",
                                    }}
                                    width="5%"
                                  >
                                    {language ? "क्रम संख्या" : "Sr.No."}
                                  </th>
                                  {headers.map((header, idx) => (
                                    <th
                                      key={idx}
                                      style={{
                                        minWidth: "125px",
                                        border: "1px solid #9ca3af",
                                        padding: "8px",
                                        textAlign: "center",
                                        fontSize: "0.875rem",
                                      }}
                                      width="25%"
                                    >
                                      {language
                                        ? header?.label?.hi
                                        : header?.label?.en}
                                    </th>
                                  ))}
                                  <th
                                    style={{
                                      border: "1px solid #9ca3af",
                                      padding: "8px",
                                      textAlign: "center",
                                      fontSize: "0.875rem",
                                    }}
                                  >
                                    {language ? "कार्रवाई" : "Action"}
                                  </th>
                                </tr>
                              </thead>
                              <tbody>
                                {rows.map((row, rowIndex) => (
                                  <tr key={rowIndex}>
                                    <td
                                      style={{
                                        border: "1px solid #9ca3af",
                                        padding: "8px",
                                        color: "#374151",
                                        fontSize: "0.875rem",
                                        textAlign: "center",
                                      }}
                                    >
                                      {rowIndex + 1}
                                    </td>
                                    {headers.map((header, colIndex) => {
                                      const {
                                        name,
                                        type = "text",
                                        placeholder,
                                        maxLength,
                                        options,
                                        disabled = false,
                                      } = header;
                                      const fieldError =
                                        errors[
                                          `${tableName}.${rowIndex}.${name}`
                                        ] || null;

                                      return (
                                        <td
                                          key={colIndex}
                                          style={{
                                            border: "1px solid #9ca3af",
                                            padding: "8px",
                                          }}
                                        >
                                          {type === "select" ? (
                                            <select
                                              name={`${tableName}[${rowIndex}][${name}]`}
                                              className="mt-1 w-full border rounded text-sm p-2"
                                              value={row[name] || ""}
                                              disabled={disabled}
                                              style={{
                                                width: "100%",
                                              }}
                                              onChange={(e) =>
                                                handleInputChange(
                                                  tableName,
                                                  rows,
                                                  e,
                                                  rowIndex,
                                                  name
                                                )
                                              }
                                            >
                                              <option value="">
                                                {language
                                                  ? "विकल्प चुनें"
                                                  : "Select option"}
                                              </option>
                                              {getFilteredOptions(
                                                options,
                                                rows,
                                                rowIndex,
                                                name
                                              ).map((opt, i) => (
                                                <option
                                                  key={i}
                                                  value={opt.value}
                                                  disabled={opt.isDisabled}
                                                >
                                                  {opt.label}
                                                </option>
                                              ))}
                                            </select>
                                          ) : (
                                            <input
                                              type={type}
                                              name={`${tableName}[${rowIndex}][${name}]`}
                                              placeholder={placeholder || ""}
                                              style={{
                                                marginTop: "4px",
                                                width: "100%",
                                                border: "1px solid #d1d5db",
                                                borderRadius: "0.25rem",
                                                fontSize: "0.875rem",
                                                padding: "8px",
                                              }}
                                              min={1}
                                              value={row[name] || ""}
                                              disabled={disabled}
                                              maxLength={maxLength || 255}
                                              onKeyDown={
                                                type === "number"
                                                  ? preventInvalidNumberKeys
                                                  : undefined
                                              }
                                              onChange={(e) =>
                                                handleInputChange(
                                                  tableName,
                                                  rows,
                                                  e,
                                                  rowIndex,
                                                  name
                                                )
                                              }
                                            />
                                          )}
                                          {fieldError && (
                                            <p
                                              style={{
                                                color: "#ef4444",
                                                fontSize: "12px",
                                              }}
                                            >
                                              {language
                                                ? fieldError.hi
                                                : fieldError.en}
                                            </p>
                                          )}
                                        </td>
                                      );
                                    })}
                                    <td
                                      style={{
                                        textAlign: "center",
                                        border: "1px solid #9ca3af",
                                        padding: "8px",
                                      }}
                                    >
                                      {rows?.length > 1 && (
                                        <button
                                          type="button"
                                          onClick={() =>
                                            removeRow(tableName, rows, rowIndex)
                                          }
                                          style={{
                                            marginTop: "8px",
                                            padding: "8px 12px",
                                            backgroundColor: "#ef4444",
                                            color: "#ffffff",
                                            fontSize: "0.875rem",
                                            borderRadius: "6px",
                                            border: "none",
                                            cursor: "pointer",
                                          }}
                                        >
                                          {language ? "पंक्ति हटाएँ" : "Remove"}
                                        </button>
                                      )}
                                    </td>
                                  </tr>
                                ))}
                              </tbody>
                            </table>
                            <button
                              type="button"
                              onClick={() => {
                                addRow(tableName, rows, headers);
                              }}
                              style={{
                                marginTop: "8px",
                                padding: "4px 12px",
                                backgroundColor: "#0d9488",
                                color: "#ffffff",
                                fontSize: "0.875rem",
                                borderRadius: "6px",
                                border: "none",
                                cursor: "pointer",
                              }}
                            >
                              {language ? "नई पंक्ति जोड़ें" : "Add Row"}
                            </button>
                          </div>
                        </div>
                      );
                    }

                    if (type === "select") {
                      return (
                        <Select
                          value={value || ""}
                          style={customStylesAccUser}
                          theme={selectThemeUser}
                        >
                          <option value="" disabled hidden>
                            {placeholder || "Select an option"}
                          </option>
                          {options.map((opt) => (
                            <option key={opt.value} value={opt.value}>
                              {opt.label}
                            </option>
                          ))}
                        </Select>
                      );
                    }

                    /* ================= NORMAL FIELD ================= */
                    return (
                      <div className="col-md-4 mb-3" key={fieldIndex}>
                        <div className="f_fields">
                          <label htmlFor={htmlFor} className="form-label">
                            <span className="field-label">
                              {language ? label?.hi : label?.en}
                            </span>
                          </label>

                          <input
                            type={type}
                            id={htmlFor}
                            name={htmlFor}
                            className={"form-control"}
                            value={value}
                            placeholder={placeholder}
                            onChange={(e) => handleChange(e)}
                            required={validation.required}
                            disabled={true}
                          />
                          {errors[field.inputProps.name] && (
                            <p
                              style={{
                                color: "#ef4444",
                                fontSize: "0.75rem",
                                marginTop: "4px",
                              }}
                            >
                              {language
                                ? errors[field.inputProps.name].hi
                                : errors[field.inputProps.name].en}
                            </p>
                          )}
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            </div>
          );
        })}
        <div
          style={{
            textAlign: "right",
          }}
        >
          <button
            type="button"
            onClick={() => {
              handleSubmit();
            }}
            style={{
              marginTop: "8px",
              padding: "8px 12px",
              backgroundColor: "#00684a",
              color: "#ffffff",
              fontSize: "0.875rem",
              borderRadius: "6px",
              border: "none",
              cursor: "pointer",
              textAlign: "right",
            }}
          >
            {language ? "जमा करना" : "Submit"}
          </button>
        </div>
      </div>
    </Dashboard>
  );
};

export default EditVisitorTracking;
