import React, { useState, useEffect } from "react";
import { Plus, Trash2, ArrowLeft } from "lucide-react";
import moment from "moment";
import CustomSelect2 from "Components/CustomSelect2";
import { SingleDatePicker } from "react-dates";
import { ClipLoader } from "react-spinners";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const InvoiceForm = ({
  isEdit,
  invoiceId,
  onClose,
  onSubmit,
  userDetails,
  clients,
  producers,
  mixTypes,
  loading,
  initialData,
}) => {
  const [selectedClientId, setSelectedClientId] = useState("");
  const [newClientData, setNewClientData] = useState({
    program: "",
    email: "",
  });
  const [invoiceDates, setInvoiceDates] = useState({
    invoiceDate: moment().format("YYYY-MM-DD"),
    dueDate: moment().add(30, "days").format("YYYY-MM-DD"),
  });
  const [invoiceData, setInvoiceData] = useState({
    items: [],
    depositAmount: 0,
    depositPercentage: 50,
    notes: "",
    termsAndConditions: "",
  });
  const [focusedInput, setFocusedInput] = useState({});
  const [isQuote, setIsQuote] = useState(false);

  // Initialize form with data if editing
  useEffect(() => {
    if (isEdit && initialData) {
      setInvoiceData({
        items: initialData.items.map((item) => ({
          mixDate: item.mix_date,
          producer: item.producer_id,
          mixType: item.mix_type_id,
          teamName: item.team_name,
          division: item.division,
          musicSurveyDue: item.music_survey_due,
          routineSubmissionDue: item.routine_submission_due,
          estimatedCompletion: item.estimated_completion,
          price: item.total,
        })),
        notes: initialData.invoice.notes,
        termsAndConditions: initialData.invoice.terms_and_conditions,
        depositAmount: initialData.invoice.deposit_amount,
        depositPercentage: initialData.invoice.deposit_percentage,
      });

      setSelectedClientId(initialData.invoice.client_id);
      setNewClientData({
        program: initialData.invoice.program,
        email: initialData.invoice.client_email,
      });

      setInvoiceDates({
        invoiceDate: moment(initialData.invoice.invoice_date).format(
          "YYYY-MM-DD"
        ),
        dueDate: moment(initialData.invoice.due_date).format("YYYY-MM-DD"),
      });
    }
  }, [isEdit, initialData]);

  const handleAddItem = () => {
    setInvoiceData((prev) => ({
      ...prev,
      items: [
        ...prev.items,
        {
          mixDate: "",
          producer: "",
          mixType: "",
          teamName: `Team ${prev.items.length + 1}`,
          division: "TBD",
          musicSurveyDue: "",
          routineSubmissionDue: "",
          estimatedCompletion: "",
          price: 0,
        },
      ],
    }));
  };

  const handleRemoveItem = (indexToRemove) => {
    setInvoiceData((prev) => {
      const newItems = prev.items.filter((_, index) => index !== indexToRemove);
      // Renumber team names
      const updatedItems = newItems.map((item, index) => {
        if (item.teamName.startsWith("Team ")) {
          return { ...item, teamName: `Team ${index + 1}` };
        }
        return item;
      });
      return { ...prev, items: updatedItems };
    });
  };

  const handleItemChange = (index, field, value) => {
    setInvoiceData((prev) => {
      const newItems = [...prev.items];

      if (field === "teamName") {
        if (value !== "" || !newItems[index].teamName.startsWith("Team ")) {
          newItems[index].teamName = value;
        }
      } else if (field === "division") {
        if (value !== "" || newItems[index].division !== "TBD") {
          newItems[index].division = value;
        }
      } else {
        newItems[index][field] = value;
      }

      if (field === "quantity" || field === "price") {
        newItems[index].amount =
          (newItems[index].quantity || 0) * (newItems[index].price || 0);
      }

      const subtotal = newItems.reduce(
        (sum, item) => sum + (item.amount || 0),
        0
      );
      const total = subtotal + subtotal * (prev.tax / 100);

      return {
        ...prev,
        items: newItems,
        subtotal,
        total,
      };
    });
  };

  const calculateDates = (mixDate, index) => {
    if (!mixDate) return;

    const date = moment(mixDate);

    // Parse settings
    const surveySettings = userDetails?.survey
      ? JSON.parse(userDetails.survey)
      : { weeks: 8, day: "Monday" };
    const routineSettings = userDetails?.routine_submission_date
      ? JSON.parse(userDetails.routine_submission_date)
      : { weeks: 1, day: "Monday" };
    const deliverySettings = userDetails?.estimated_delivery
      ? JSON.parse(userDetails.estimated_delivery)
      : { weeks: 1, day: "Friday" };

    // Function to find the previous occurrence of a day
    const findPreviousDay = (date, targetDay) => {
      const days = [
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
      ];
      const targetDayIndex = days.indexOf(targetDay);
      let currentDate = moment(date);

      while (currentDate.day() !== targetDayIndex) {
        currentDate.subtract(1, "days");
      }
      return currentDate;
    };

    // Calculate dates
    const surveyDate = findPreviousDay(
      moment(mixDate).subtract(surveySettings.weeks, "weeks"),
      surveySettings.day
    );
    const submissionDate = findPreviousDay(
      moment(mixDate).subtract(routineSettings.weeks, "weeks"),
      routineSettings.day
    );
    const completionDate = findPreviousDay(
      moment(mixDate).add(deliverySettings.weeks, "weeks"),
      deliverySettings.day
    );

    const newItems = [...invoiceData.items];
    newItems[index] = {
      ...newItems[index],
      musicSurveyDue: surveyDate.format("YYYY-MM-DD"),
      routineSubmissionDue: submissionDate.format("YYYY-MM-DD"),
      estimatedCompletion: completionDate.format("YYYY-MM-DD"),
    };

    setInvoiceData((prev) => ({
      ...prev,
      items: newItems,
      termsAndConditions:
        userDetails?.contract_agreement || prev.termsAndConditions,
    }));
  };

  const handleSubmit = () => {
    const formData = {
      clientId: selectedClientId ? parseInt(selectedClientId) : undefined,
      clientEmail: selectedClientId
        ? clients.find((c) => c.client_id === parseInt(selectedClientId))
            ?.client_email
        : newClientData.email,
      clientName: selectedClientId
        ? clients.find((c) => c.client_id === parseInt(selectedClientId))
            ?.client_full_name
        : undefined,
      programName: selectedClientId
        ? clients.find((c) => c.client_id === parseInt(selectedClientId))
            ?.client_program
        : newClientData.program,
      invoiceDate: invoiceDates.invoiceDate,
      dueDate: invoiceDates.dueDate,
      items: invoiceData.items.map((item) => ({
        description: `Mix Package - ${item.mixType}`,
        quantity: item.quantity,
        price: item.price,
        mixDate: item.mixDate,
        producer: item.producer,
        teamName: item.teamName,
        division: item.division,
        musicSurveyDue: item.musicSurveyDue,
        routineSubmissionDue: item.routineSubmissionDue,
        estimatedCompletion: item.estimatedCompletion,
      })),
      depositAmount: invoiceData.depositAmount || undefined,
      depositPercentage: invoiceData.depositPercentage || undefined,
      notes: invoiceData.notes,
      termsAndConditions: invoiceData.termsAndConditions,
      isQuote,
    };

    onSubmit(formData);
  };

  return (
    <div className="rounded-lg bg-boxdark p-6">
      {/* Header with back button */}
      <div className="mb-6 flex items-center justify-between">
        <button
          onClick={onClose}
          className="flex items-center gap-2 text-white hover:text-primary"
        >
          <ArrowLeft className="h-5 w-5" />
          Back to Invoices
        </button>
        <h2 className="text-2xl font-bold text-white">
          {isEdit ? "Edit Invoice" : "New Invoice"}
        </h2>
        {isEdit && (
          <button
            onClick={() => onSubmit({ ...invoiceData, resendLink: true })}
            className="flex items-center gap-2 rounded-lg bg-primary px-4 py-2 font-medium text-white hover:bg-opacity-90"
          >
            <FontAwesomeIcon icon="paper-plane" className="h-4 w-4" />
            Resend Link
          </button>
        )}
      </div>

      {/* Producer Information */}
      {userDetails && (
        <div className="mb-8 grid grid-cols-2 gap-6 rounded-lg border border-stroke/50 p-6">
          <div className="flex items-start gap-4">
            {userDetails.photo && (
              <img
                src={userDetails.photo}
                alt="Producer"
                className="h-16 w-16 rounded-full object-cover"
              />
            )}
            <div>
              <h3 className="text-xl font-semibold text-white">
                {userDetails.first_name} {userDetails.last_name}
              </h3>
              <p className="text-bodydark">{userDetails.email}</p>
              <p className="text-bodydark">{userDetails.company_name}</p>
              <p className="text-bodydark">{userDetails.office_email}</p>
            </div>
          </div>
          <div className="flex justify-end">
            {userDetails.company_logo && (
              <img
                src={userDetails.company_logo}
                alt="Company Logo"
                className="h-20 object-contain"
              />
            )}
          </div>
        </div>
      )}

      {/* Client Selection */}
      <div className="mb-8 border-b border-stroke/50 pb-8">
        <h3 className="mb-4 text-xl font-semibold text-white">
          Client Information
        </h3>
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          <div>
            <label className="mb-2.5 block font-medium text-white">
              Select Existing Client
            </label>
            <CustomSelect2
              value={selectedClientId}
              onChange={(value) => setSelectedClientId(value)}
              options={clients.map((client) => ({
                value: client.client_id,
                label: client.client_program,
              }))}
              label="Select Client"
            />
          </div>

          <div>
            <p className="mb-2.5 font-medium text-white">- OR -</p>
          </div>

          <div>
            <label className="mb-2.5 block font-medium text-white">
              New Client Program Name
            </label>
            <input
              type="text"
              value={newClientData.program}
              onChange={(e) =>
                setNewClientData((prev) => ({
                  ...prev,
                  program: e.target.value,
                }))
              }
              disabled={selectedClientId}
              className="w-full rounded border-[1.5px] border-stroke/50 bg-form-input px-5 py-3 text-white"
              placeholder="Enter program name"
            />
          </div>

          <div>
            <label className="mb-2.5 block font-medium text-white">
              New Client Email
            </label>
            <input
              type="email"
              value={newClientData.email}
              onChange={(e) =>
                setNewClientData((prev) => ({
                  ...prev,
                  email: e.target.value,
                }))
              }
              disabled={selectedClientId}
              className="w-full rounded border-[1.5px] border-stroke/50 bg-form-input px-5 py-3 text-white"
              placeholder="Enter email address"
            />
          </div>
        </div>
      </div>

      {/* Invoice Dates */}
      <div className="mb-8 border-b border-stroke/50 pb-8">
        <h3 className="mb-4 text-xl font-semibold text-white">Invoice Dates</h3>
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          <div>
            <label className="mb-2.5 block font-medium text-white">
              Invoice Date
            </label>
            <input
              type="date"
              value={invoiceDates.invoiceDate}
              onChange={(e) =>
                setInvoiceDates((prev) => ({
                  ...prev,
                  invoiceDate: e.target.value,
                }))
              }
              className="w-full rounded border-[1.5px] border-stroke/50 bg-form-input px-5 py-3 text-white"
            />
          </div>

          <div>
            <label className="mb-2.5 block font-medium text-white">
              Due Date
            </label>
            <input
              type="date"
              value={invoiceDates.dueDate}
              onChange={(e) =>
                setInvoiceDates((prev) => ({
                  ...prev,
                  dueDate: e.target.value,
                }))
              }
              className="w-full rounded border-[1.5px] border-stroke/50 bg-form-input px-5 py-3 text-white"
            />
          </div>
        </div>
      </div>

      {/* Invoice Items */}
      <div className="mb-8">
        <div className="mb-4 flex items-center justify-between">
          <h3 className="text-xl font-semibold text-white">Invoice Items</h3>
          <button
            onClick={handleAddItem}
            className="flex items-center gap-2 rounded-lg bg-primary px-4 py-2 font-medium text-white hover:bg-opacity-90"
          >
            <Plus className="h-5 w-5" />
            Add Row
          </button>
        </div>
        <div className="custom-overflow min-h-[140px] overflow-x-auto">
          <table className="w-full table-auto">
            <thead className="bg-meta-4">
              <tr>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Mix Date
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Producer
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Mix Type
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Team Name
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Division
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Survey Due
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Submission Due
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Est. Completion
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Price
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white">
                  Actions
                </th>
              </tr>
            </thead>
            <tbody className="text-white">
              {invoiceData.items.map((item, index) => (
                <tr
                  key={index}
                  className="border-b border-stroke/50 hover:bg-primary/5"
                >
                  <td className="row-date whitespace-nowrap px-4 py-3">
                    <SingleDatePicker
                      id={`mixDate_${index}`}
                      date={item.mixDate ? moment(item.mixDate) : null}
                      onDateChange={(date) => {
                        handleItemChange(
                          index,
                          "mixDate",
                          date ? date.format("YYYY-MM-DD") : null
                        );
                        calculateDates(
                          date ? date.format("YYYY-MM-DD") : null,
                          index
                        );
                      }}
                      focused={focusedInput[`mixDate_${index}`]}
                      onFocusChange={({ focused }) =>
                        setFocusedInput((prev) => ({
                          ...prev,
                          [`mixDate_${index}`]: focused,
                        }))
                      }
                      numberOfMonths={1}
                      isOutsideRange={() => false}
                      displayFormat="MM-DD-YYYY"
                      placeholder="Select Mix Date"
                      readOnly={true}
                      customInputIcon={null}
                      noBorder={true}
                      block
                      className="w-full rounded border border-stroke/50"
                    />
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <CustomSelect2
                      value={item.producer}
                      onChange={(value) =>
                        handleItemChange(index, "producer", value)
                      }
                      className="h-[36px] w-[150px] rounded border-[1.5px] border-stroke/50 bg-transparent px-5 py-3 outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:focus:border-primary"
                    >
                      <option value="">Select Producer</option>
                      {producers.map((producer) => (
                        <option key={producer.id} value={producer.id}>
                          {producer.name}
                        </option>
                      ))}
                    </CustomSelect2>
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <CustomSelect2
                      value={item.mixType}
                      onChange={(value) => {
                        handleItemChange(index, "mixType", value);
                        const selectedMixType = mixTypes.find(
                          (mt) => mt.id === parseInt(value)
                        );
                        if (selectedMixType) {
                          handleItemChange(
                            index,
                            "price",
                            selectedMixType.price
                          );
                        }
                      }}
                      className="h-[36px] w-[150px] rounded border-[1.5px] border-stroke/50 bg-transparent px-5 py-3 outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:focus:border-primary"
                    >
                      <option value="">Select Mix Type</option>
                      {mixTypes.map((mixType) => (
                        <option key={mixType.id} value={mixType.id}>
                          {mixType.name} - ${mixType.price}
                        </option>
                      ))}
                    </CustomSelect2>
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <input
                      type="text"
                      value={item.teamName}
                      onChange={(e) =>
                        handleItemChange(index, "teamName", e.target.value)
                      }
                      onFocus={(e) => {
                        if (e.target.value.startsWith("Team ")) {
                          handleItemChange(index, "teamName", "");
                        }
                      }}
                      className="w-full min-w-[150px] rounded border border-stroke/50 bg-transparent px-2 py-1 text-white"
                    />
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <input
                      type="text"
                      value={item.division}
                      onChange={(e) =>
                        handleItemChange(index, "division", e.target.value)
                      }
                      onFocus={(e) => {
                        if (e.target.value === "TBD") {
                          handleItemChange(index, "division", "");
                        }
                      }}
                      className="w-full min-w-[150px] rounded border border-stroke/50 bg-transparent px-2 py-1 text-white"
                    />
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <input
                      type="date"
                      value={item.musicSurveyDue}
                      readOnly
                      className="w-full min-w-[150px] rounded border border-stroke/50 bg-transparent px-2 py-1 text-white"
                    />
                  </td>
                  <td className="row-date whitespace-nowrap px-4 py-3">
                    <SingleDatePicker
                      id={`routineSubmissionDue_${index}`}
                      date={
                        item.routineSubmissionDue
                          ? moment(item.routineSubmissionDue)
                          : null
                      }
                      onDateChange={(date) =>
                        handleItemChange(
                          index,
                          "routineSubmissionDue",
                          date ? date.format("YYYY-MM-DD") : null
                        )
                      }
                      focused={focusedInput[`routineSubmissionDue_${index}`]}
                      onFocusChange={({ focused }) =>
                        setFocusedInput((prev) => ({
                          ...prev,
                          [`routineSubmissionDue_${index}`]: focused,
                        }))
                      }
                      numberOfMonths={1}
                      isOutsideRange={() => false}
                      displayFormat="MM-DD-YYYY"
                      placeholder="Select Due Date"
                      readOnly={true}
                      customInputIcon={null}
                      noBorder={true}
                      block
                      className="w-full rounded border border-stroke/50"
                    />
                  </td>
                  <td className="row-date whitespace-nowrap px-4 py-3">
                    <SingleDatePicker
                      id={`estimatedCompletion_${index}`}
                      date={
                        item.estimatedCompletion
                          ? moment(item.estimatedCompletion)
                          : null
                      }
                      onDateChange={(date) =>
                        handleItemChange(
                          index,
                          "estimatedCompletion",
                          date ? date.format("YYYY-MM-DD") : null
                        )
                      }
                      focused={focusedInput[`estimatedCompletion_${index}`]}
                      onFocusChange={({ focused }) =>
                        setFocusedInput((prev) => ({
                          ...prev,
                          [`estimatedCompletion_${index}`]: focused,
                        }))
                      }
                      numberOfMonths={1}
                      isOutsideRange={() => false}
                      displayFormat="MM-DD-YYYY"
                      placeholder="Select Completion Date"
                      readOnly={true}
                      customInputIcon={null}
                      noBorder={true}
                      block
                      className="w-full rounded border border-stroke/50"
                    />
                  </td>
                  <td className="row-date whitespace-nowrap px-4 py-3">
                    <input
                      type="number"
                      value={item.price}
                      onChange={(e) =>
                        handleItemChange(
                          index,
                          "price",
                          parseFloat(e.target.value)
                        )
                      }
                      className="w-24 rounded border border-stroke/50 bg-transparent px-2 py-1 text-white"
                      min="0"
                      placeholder="$0.00"
                    />
                  </td>
                  <td className="whitespace-nowrap px-4 py-3">
                    <button
                      onClick={() => handleRemoveItem(index)}
                      className="p-1 text-danger hover:text-danger/80"
                    >
                      <Trash2 className="h-5 w-5" />
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {/* Deposit Section */}
      <div className="mt-6 grid grid-cols-2 gap-6">
        <div>
          <label className="mb-2 block text-white">Deposit Type</label>
          <select
            value={invoiceData.depositAmount ? "amount" : "percentage"}
            onChange={(e) => {
              if (e.target.value === "amount") {
                setInvoiceData((prev) => ({
                  ...prev,
                  depositPercentage: 0,
                }));
              } else {
                setInvoiceData((prev) => ({ ...prev, depositAmount: 0 }));
              }
            }}
            className="w-full rounded-lg border border-stroke bg-transparent px-4 py-2 text-white"
          >
            <option value="percentage">Percentage</option>
            <option value="amount">Fixed Amount</option>
          </select>
        </div>
        <div>
          <label className="mb-2 block text-white">
            {invoiceData.depositAmount
              ? "Deposit Amount"
              : "Deposit Percentage"}
          </label>
          <input
            type="number"
            value={invoiceData.depositAmount || invoiceData.depositPercentage}
            onChange={(e) => {
              const value = parseFloat(e.target.value);
              if (invoiceData.depositAmount) {
                setInvoiceData((prev) => ({
                  ...prev,
                  depositAmount: value,
                }));
              } else {
                setInvoiceData((prev) => ({
                  ...prev,
                  depositPercentage: value,
                }));
              }
            }}
            className="w-full rounded-lg border border-stroke bg-transparent px-4 py-2 text-white"
            min="0"
            max={invoiceData.depositAmount ? undefined : 100}
          />
        </div>
      </div>

      {/* Notes and Terms */}
      <div className="mt-6 grid grid-cols-1 gap-6">
        <div>
          <label className="mb-2 block text-white">Notes</label>
          <textarea
            value={invoiceData.notes}
            onChange={(e) =>
              setInvoiceData((prev) => ({ ...prev, notes: e.target.value }))
            }
            className="w-full rounded-lg border border-stroke bg-transparent px-4 py-2 text-white"
            rows="3"
            placeholder="Add any additional notes..."
          />
        </div>
        <div>
          <label className="mb-2 block text-white">Terms and Conditions</label>
          <textarea
            value={invoiceData.termsAndConditions}
            onChange={(e) =>
              setInvoiceData((prev) => ({
                ...prev,
                termsAndConditions: e.target.value,
              }))
            }
            className="w-full rounded-lg border border-stroke bg-transparent px-4 py-2 text-white"
            rows="3"
            placeholder="Add terms and conditions..."
          />
        </div>
      </div>

      {/* Action Buttons */}
      <div className="mt-6 flex justify-end gap-4">
        <button
          onClick={onClose}
          className="rounded-lg border border-stroke px-6 py-2 text-bodydark hover:bg-stroke"
        >
          Cancel
        </button>

        <button
          onClick={() => {
            setIsQuote(false);
            handleSubmit();
          }}
          disabled={loading}
          className="rounded-lg bg-primary px-6 py-2 text-white hover:bg-opacity-90 disabled:opacity-50"
        >
          {loading ? "Saving..." : isEdit ? "Save Changes" : "Create Invoice"}
        </button>
      </div>
    </div>
  );
};

export default InvoiceForm;
