import React, { useState, useEffect, useContext } from "react";
import { AuthContext } from "Src/authContext";
import { GlobalContext, showToast } from "Src/globalContext";
import { updateRequest, createRequest } from "Src/context/Global/GlobalActions";
import MkdSDK from "Utils/MkdSDK";
import {
  Plus,
  FileText,
  Download,
  Trash2,
  ArrowLeft,
  Pencil,
} from "lucide-react";
import { getUserDetailsByIdAPI } from "Src/services/userService";
import { SingleDatePicker } from "react-dates";
import "react-dates/initialize";
import "react-dates/lib/css/_datepicker.css";
import moment from "moment";
import { ClipLoader } from "react-spinners";
import { getAllClientsAPI } from "Src/services/clientService";
import { getAllMixTypeAPI } from "Src/services/mixTypeServices";
import CustomSelect2 from "Components/CustomSelect2";
import { useNavigate } from "react-router-dom";
import { sendEmailAPIV3 } from "Src/services/emailService";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import EditInvoiceComponent from "Components/Invoice/EditInvoiceComponent";
import ManagerCreateInvoiceComponent from "Components/Invoice/ManagerCreateInvoiceComponent";
import ManagerEditInvoiceComponent from "Components/Invoice/ManagerEditInvoiceComponent";

const ManagerInvoicePage = () => {
  const { state: authState, dispatch: authDispatch } =
    React.useContext(AuthContext);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);
  const [showNewInvoice, setShowNewInvoice] = useState(false);
  const [editInvoiceId, setEditInvoiceId] = useState(null);
  const [loading, setLoading] = useState(true);
  const [invoices, setInvoices] = useState([]);
  const [userDetails, setUserDetails] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageCount, setPageCount] = useState(1);
  const [dataTotal, setDataTotal] = useState(0);
  const [clients, setClients] = useState([]);
  const [mixTypes, setMixTypes] = useState([]);
  const pageSize = 10;
  const sdk = new MkdSDK();
  const navigate = useNavigate();

  useEffect(() => {
    globalDispatch({
      type: "SETPATH",
      payload: { path: "invoices" },
    });
    fetchInvoices();

    const userId = localStorage.getItem("user");
    if (userId) {
      getUserDetails(userId);
    }

    fetchAvailableClients();
    getAllMixTypes();
  }, [currentPage]);

  const getUserDetails = async (userId) => {
    try {
      const result = await getUserDetailsByIdAPI(userId);
      if (!result.error) {
        setUserDetails(result.model);
      }
    } catch (error) {
      console.error("Error fetching user details:", error);
      showToast(globalDispatch, "Failed to fetch company details", "error");
    }
  };

  const fetchAvailableClients = async () => {
    try {
      const result = await getAllClientsAPI();
      if (!result.error) {
        setClients(result.list);
      }
    } catch (error) {
      showToast(globalDispatch, "Failed to fetch clients", "error");
    }
  };

  const getAllMixTypes = async () => {
    try {
      const result = await getAllMixTypeAPI();
      if (!result.error && result.list.length > 0) {
        setMixTypes(result.list);
      }
    } catch (error) {
      showToast(globalDispatch, "Failed to fetch mix types", "error");
    }
  };

  const fetchInvoices = async () => {
    try {
      setLoading(true);
      const result = await sdk.getInvoices(currentPage, pageSize);
      setInvoices(result.invoices || []);
      setPageCount(result.num_pages || 1);
      setDataTotal(result.total || 0);
    } catch (error) {
      console.error("Error fetching invoices:", error);
      showToast(globalDispatch, "Failed to fetch invoices", "error");
    } finally {
      setLoading(false);
    }
  };

  const handleUpdateInvoice = async (formData) => {
    try {
      setLoading(true);
      const payload = {
        client_id: formData.selectedClientId
          ? parseInt(formData.selectedClientId)
          : undefined,
        invoice_date: formData.invoiceDates.invoiceDate,
        due_date: formData.invoiceDates.dueDate,
        notes: formData.invoiceData.notes,
        terms_and_conditions: formData.invoiceData.termsAndConditions,
        deposit_amount: formData.invoiceData.depositAmount,
        deposit_percentage: formData.invoiceData.depositPercentage,
      };

      formData.invoiceData.items.forEach(async (item) => {
        if (item.id) {
          await updateRequest(
            globalDispatch,
            authDispatch,
            "invoice_item",
            item.id,
            {
              team_name: item.teamName,
              division: item.division,
              music_survey_due: item.musicSurveyDue,
              routine_submission_due: item.routineSubmissionDue,
              estimated_completion: item.estimatedCompletion,
              price: item.price,
              mix_date: item.mixDate,
              producer: item.producer,
              quantity: item.quantity,
              description: `Mix Package - ${item.mixType}`,
            },
            false
          );
        } else {
          await createRequest(
            globalDispatch,
            authDispatch,
            "invoice_item",
            {
              invoice_id: editInvoiceId,
              team_name: item.teamName,
              division: item.division,
              music_survey_due: item.musicSurveyDue,
              routine_submission_due: item.routineSubmissionDue,
              estimated_completion: item.estimatedCompletion,
              price: item.price,
              mix_date: item.mixDate,
              producer: item.producer,
              quantity: item.quantity,
              description: `Mix Package - ${item.mixType}`,
            },
            false
          );
        }
      });

      const result = await updateRequest(
        globalDispatch,
        authDispatch,
        "invoice",
        editInvoiceId,
        payload
      );

      if (!result.error) {
        setEditInvoiceId(null);
        fetchInvoices();
        showToast(globalDispatch, "Invoice updated successfully", "success");
      }
    } catch (error) {
      console.error("Error updating invoice:", error);
      showToast(globalDispatch, "Failed to update invoice", "error");
    } finally {
      setLoading(false);
    }
  };

  const handleCreateInvoice = async (formData) => {
    try {
      setLoading(true);
      const result = await sdk.createInvoice({
        ...formData,
        producer: localStorage.getItem("user"),
      });

      if (!result.error) {
        setShowNewInvoice(false);
        fetchInvoices();
        showToast(
          globalDispatch,
          formData.isQuote
            ? "Quote created successfully"
            : "Invoice created successfully",
          "success"
        );
      }
    } catch (error) {
      console.error("Error creating invoice:", error);
      showToast(
        globalDispatch,
        `Failed to create ${formData.isQuote ? "quote" : "invoice"}`,
        "error"
      );
    } finally {
      setLoading(false);
    }
  };

  const handleResendLink = async (invoiceId) => {
    try {
      const invoiceDetails = await sdk.callRawAPI(
        `/v3/api/custom/equality_record/subscription/invoice/${invoiceId}`,
        {},
        "GET"
      );

      if (!invoiceDetails.error) {
        const emailResult = await sendEmailAPIV3({
          from: "myeq@equalityrecords.com",
          to: invoiceDetails.invoice.client_email,
          subject: invoiceDetails.invoice.is_quote
            ? "Quote Available - Action Required"
            : "Invoice Available - Action Required",
          body: `
            <p>Hello${
              invoiceDetails.invoice.client_name
                ? ` ${invoiceDetails.invoice.client_name}`
                : ""
            },</p>
            <p>Your ${
              invoiceDetails.invoice.is_quote ? "quote" : "invoice"
            } is ready for your review.</p>
            <p><a href="https://equalityrecords.com/invoice/${invoiceId}/${
            invoiceDetails.invoice.access_token
          }">View ${
            invoiceDetails.invoice.is_quote ? "Quote" : "Invoice"
          }</a></p>
            <p>Thank you!</p>
            <p>${userDetails?.company_name || ""}</p>
          `,
        });

        if (!emailResult.error) {
          showToast(
            globalDispatch,
            "Invoice link resent successfully",
            "success"
          );
        } else {
          showToast(
            globalDispatch,
            "Failed to send email notification",
            "error"
          );
        }
      }
    } catch (error) {
      showToast(globalDispatch, "Failed to resend invoice link", "error");
    }
  };

  const handleEditInvoice = async (invoiceId) => {
    try {
      setLoading(true);
      const sdk = new MkdSDK();
      const result = await sdk.getInvoiceById(invoiceId);

      if (!result.error) {
        setEditInvoiceId(invoiceId);
      }
    } catch (error) {
      console.error("Error fetching invoice details:", error);
      showToast(globalDispatch, "Failed to fetch invoice details", "error");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="p-4 mx-auto max-w-screen md:p-6 2xl:p-10">
      {showNewInvoice ? (
        <ManagerCreateInvoiceComponent
          onClose={() => {
            window.confirm("Are you sure you want to close this invoice?") &&
              setShowNewInvoice(false);
          }}
          onSubmit={handleCreateInvoice}
          userDetails={userDetails}
          clients={clients}
          mixTypes={mixTypes}
          loading={loading}
        />
      ) : editInvoiceId ? (
        <ManagerEditInvoiceComponent
          id={editInvoiceId}
          onClose={() => {
            window.confirm("Are you sure you want to close this invoice?") &&
              setEditInvoiceId(null);
          }}
          onSubmit={handleUpdateInvoice}
          onResend={() => handleResendLink(editInvoiceId)}
          clients={clients}
          mixTypes={mixTypes}
          userDetails={userDetails}
        />
      ) : (
        <>
          <div className="mb-5 rounded border shadow-default border-stroke/50 bg-boxdark">
            <div className="flex justify-between items-center px-4 py-5 mb-6 md:px-6 2xl:px-9">
              <div>
                <h2 className="text-2xl font-bold text-white">Invoices</h2>
                <p className="mt-1 text-lg text-bodydark">
                  Manage your invoices
                </p>
              </div>
              <button
                onClick={() => {
                  setEditInvoiceId(null);
                  setShowNewInvoice(!showNewInvoice);
                }}
                className="flex gap-2 items-center px-4 py-2 font-medium text-white rounded-lg bg-primary hover:bg-opacity-90"
              >
                <Plus className="w-5 h-5" />
                New Invoice
              </button>
            </div>
          </div>

          <div className="rounded border shadow-default border-strokedark bg-boxdark">
            <div className="flex justify-between items-center px-4 border-b border-strokedark md:px-6 2xl:px-9">
              <h4 className="my-3 text-2xl font-semibold text-white">
                Invoices
              </h4>
            </div>

            <div className="p-4 md:p-6 2xl:p-10">
              <div className="custom-overflow text-[12p 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-xs font-medium tracking-wider text-left uppercase text-bodydark1">
                        Invoice ID
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-left uppercase text-bodydark1">
                        Client Name
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-left uppercase text-bodydark1">
                        Program
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-left uppercase text-bodydark1">
                        Email
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-right uppercase text-bodydark1">
                        Total
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-right uppercase text-bodydark1">
                        Deposit
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-center uppercase text-bodydark1">
                        Status
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-left uppercase text-bodydark1">
                        Created
                      </th>
                      <th className="px-4 py-3 text-xs font-medium tracking-wider text-center uppercase text-bodydark1">
                        Actions
                      </th>
                    </tr>
                  </thead>
                  {!loading && invoices.length > 0 ? (
                    <tbody className="text-white">
                      {invoices.map((invoice) => (
                        <tr
                          key={invoice.id}
                          className="text-xs border-b cursor-pointer border-strokedark hover:bg-primary/5"
                          onClick={() =>
                            navigate(`/manager/invoice/${invoice.id}`)
                          }
                        >
                          <td className="px-4 py-4 whitespace-nowrap">
                            #{invoice.id}
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            {invoice.client_name}
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            {invoice.program}
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            {invoice.client_email}
                          </td>
                          <td className="px-4 py-4 text-right whitespace-nowrap">
                            ${parseFloat(invoice.total).toFixed(2)}
                          </td>
                          <td className="px-4 py-4 text-right whitespace-nowrap">
                            <div>
                              ${parseFloat(invoice.deposit_amount).toFixed(2)}
                              <span className="ml-1 text-xs text-bodydark2">
                                ({invoice.deposit_percentage}%)
                              </span>
                            </div>
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            <div className="flex justify-center">
                              <span
                                className={`inline-block rounded px-2.5 py-0.5 text-sm font-medium ${
                                  invoice.status === "paid"
                                    ? "bg-success/10 text-success"
                                    : invoice.status === "pending"
                                    ? "bg-warning/10 text-warning"
                                    : invoice.status === "overdue"
                                    ? "bg-danger/10 text-danger"
                                    : "bg-primary/10 text-primary"
                                }`}
                              >
                                {invoice.status}
                              </span>
                            </div>
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            {moment(new Date(invoice.create_at)).format(
                              "MMM DD, YYYY"
                            )}
                          </td>
                          <td className="px-4 py-4 whitespace-nowrap">
                            <div className="flex gap-2 justify-center items-center">
                              <button
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleEditInvoice(invoice.id);
                                }}
                                className="bg-primary px-3 py-1.5 text-sm font-medium text-white hover:bg-opacity-90"
                              >
                                Edit
                              </button>
                              <button
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleResendLink(invoice.id);
                                }}
                                className="bg-success px-3 py-1.5 text-sm font-medium text-white hover:bg-opacity-90"
                              >
                                Resend
                              </button>
                            </div>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  ) : loading ? (
                    <tbody>
                      <tr>
                        <td colSpan={9} className="text-center">
                          <div className="flex h-[140px] items-center justify-center">
                            <ClipLoader color="#fff" size={30} />
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  ) : (
                    <tbody>
                      <tr>
                        <td colSpan={9} className="text-center">
                          <div className="flex h-[140px] items-center justify-center">
                            <span className="text-bodydark">
                              No invoices found
                            </span>
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  )}
                </table>
              </div>

              {pageCount > 1 && (
                <div className="flex justify-between items-center px-4 py-5">
                  <div className="flex gap-4 items-center">
                    <button
                      onClick={() =>
                        setCurrentPage((prev) => Math.max(prev - 1, 1))
                      }
                      disabled={currentPage === 1}
                      className="flex justify-center items-center px-4 py-2 text-white rounded bg-primary hover:bg-opacity-90 disabled:bg-opacity-50"
                    >
                      Previous
                    </button>
                    <button
                      onClick={() =>
                        setCurrentPage((prev) => Math.min(prev + 1, pageCount))
                      }
                      disabled={currentPage === pageCount}
                      className="flex justify-center items-center px-4 py-2 text-white rounded bg-primary hover:bg-opacity-90 disabled:bg-opacity-50"
                    >
                      Next
                    </button>
                  </div>
                  <span className="text-sm text-bodydark2">
                    Page {currentPage} of {pageCount} ({dataTotal} total)
                  </span>
                </div>
              )}
            </div>
          </div>
        </>
      )}
    </div>
  );
};

export default ManagerInvoicePage;
