import axios from 'axios';
import React, { useEffect, useState } from 'react';
import Image from "next/image";
import { useRouter } from 'next/navigation';
import Cookies from "js-cookie";
import Link from 'next/link';

type ActivityData = {
  _id: string;
  userId: string;
  username: string;
  source: string;
  page: string;
  url: string | null;
  from: string;
  deviceId: string;
  phone?: string;
  ipAddress: string;
  userAgent: string | object;
  updated_at: string;
  created_at: string;
};

type ActivityType = {
  count: number;
  data: ActivityData[];
};

type Types = Record<string, ActivityType>;

function getTitleCase(text: string) {
  return text
    .replaceAll('/', ' ')
    .replaceAll('_', ' ')
    .replaceAll(/([a-z])([A-Z])/g, '$1 $2')
    .split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join(' ');
}

const Home = () => {
  const [date, setDate] = useState(new Date().toISOString().split('T')[0]);
  const [types, setTypes] = useState<Types>({});
  const [openedType, setOpenedType] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<any>(null);

  const merge_list = {
    "Home Page": [/home page/i, /home/i, /\//i],

    "Men Category": [/Men category/i],
    "Women Category": [/Women category/i],
    "Boys Category": [/Boys category/i],
    "Girls Category": [/Girls category/i],
    "Hair Category": [/Hair category/i],
    "Beauty Category": [/Beauty category/i],
    "Jewellery Category": [/Jewellery category/i],

    "User Wishlist Page": [/my wishlist/i, /wishlist/i],
    "User Orders Page": [/my orders/i],
    "Sell Page": [/sell page/i, /sell/i],
    "Buy Page": [/buy page/i, /buy/i],
    "Product Details Page": [/product details/i],
    "User Edit Profile Page": [/edit profile/i],
    "User Profile Page": [/profile page/i, /\/profile page/i],
    "User Page": [/user/i],
    "Search": [/search product/i, /search/i],
    "Removed From Bag": [/remove_from_bag/i],
    "Add to bag": [/add to beg/i],

    "Contact Page": [/contact us/i, /contact/i, /\/contact/i],
    "About Page": [/about us/i, /about/i, /\/about/i],
    "Privacy Policy": [/privacy policy/i, /\/privacy-policy/i],
    "Help Page": [/help/i],
    "FAQ Page": [/\/faq/i, /faq/i],

    "User Upload Page": [/my upload/i, /my uploads/i],
    "Sold Product Page": [/sold product/i],
    "User Logged Out": [/log_out/i, /log out/i],
    "Download App": [/download app/i],
  };

  function getFormattedTime(date: Date | string): string {
    if (typeof date === "string") {
      date = new Date(date);
    }

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');

    const formattedDate = `${day}-${month}-${year}`;

    let hours = date.getHours();
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const ampm = hours >= 12 ? 'PM' : 'AM';

    hours = hours % 12;
    hours = hours || 12;

    return `${formattedDate} ${String(hours).padStart(2, '0')}:${minutes} ${ampm}`;
  }

  function wrapLongLines(text: string | null, wrapLength: number) {
    if (text === null || wrapLength <= 0) {
      return <></>;
    }

    if (text.length <= wrapLength) {
      return <>{text}</>;
    }
  
    const chunks = [];
    for (let i = 0; i < text.length; i += wrapLength) {
      chunks.push(text.slice(i, i + wrapLength));
    }
  
    return (
      <>
        {chunks.map((chunk, index) => (
          <React.Fragment key={index}>
            {chunk}
            {index < chunks.length - 1 && <br />}
          </React.Fragment>
        ))}
      </>
    );
  }

  useEffect(() => {
    const fetchData = async () => {
      const token = Cookies.get("jazz_token");
      if (!token) {
        setError('No token found');
        setLoading(false);
        return;
      }

      try {
        const response = await axios.post('https://api.jazzagain.com/public/index.php/api/getallActivity', {
          date: date
        }, {
          headers: {
            Authorization: `Bearer ${token}`
          }
        });

        const rawData = response.data.data;
        const filteredData: Types = {};

        for (const [newType, patterns] of Object.entries(merge_list)) {
          const mergedData: ActivityData[] = [];
          let totalCount = 0;

          for (const type in rawData) {
            const matchesPattern = patterns.some(pattern => pattern.test(type));
            if (matchesPattern) {
              mergedData.push(...rawData[type].data);
              totalCount += rawData[type].count;
            }
          }

          if (mergedData.length > 0) {
            filteredData[newType] = {
              count: totalCount,
              data: mergedData
            };
          }
        }

        setTypes(filteredData);
      } catch (error) {
        setError(error);
      }
      setLoading(false);
    };

    fetchData();
  }, [date]);

  const handleTypeClick = (type: string) => {
    setOpenedType(type);
  };

  const handleBack = () => {
    setOpenedType(null);
  };

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  const columns = ["UserId", "Source", "From", "DeviceId", "IP Address", "Created Date"];

  const sortedTypes = Object.entries(types).sort(([, a], [, b]) => b.count - a.count);

  return (
    <>
      {loading ? (
        <div className="flex justify-center items-center p-12">
          <Image
            src={"/images/loading.gif"}
            height={50}
            width={50}
            alt="loading..."
          />
        </div>
      ) : (
        <div className="p-4">
          <div className="flex flex-col">
            <div className="flex items-center justify-center">
              <input
                type="date"
                value={date}
                onChange={(e) => setDate(e.target.value)}
                className="mb-4 p-2 border border-gray-300 rounded"
              />
            </div>
            {openedType ? (
              <div className="overflow-hidden">
                <div className="flex items-center mb-4">
                  <button
                    onClick={handleBack}
                    className="p-2 bg-blue-500 text-white rounded"
                  >
                    Back
                  </button>
                  <div className="flex-1 flex justify-center items-center">
                    <h2 className="font-semibold text-xl">{openedType}</h2>
                  </div>
                  <div></div>
                </div>
                <div className="overflow-auto bg-white border border-gray-300">
                  <table className="min-w-full border-0">
                    <thead>
                      <tr>
                        {columns.map((col) => (
                          <th
                            key={col}
                            className="p-2 border-y border-gray-300 whitespace-nowrap"
                          >
                            {col}
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody className="bg-zinc-100 text-sm text-center">
                      {types[openedType].data.map((item, index) => (
                        <tr key={index} className='hover:bg-zinc-200'>
                          <td className="p-2 border-y border-gray-300 whitespace-nowrap">
                            {(item["username"] !== "Unknown") ? item["username"] : ""}
                          </td>
                          <td className="p-2 border-y border-gray-300 whitespace-nowrap">{item["source"]}</td>
                          <td className="p-2 border-y border-gray-300">{wrapLongLines(item["from"], 80)}</td>
                          <td className="p-2 border-y border-gray-300">{wrapLongLines(item["deviceId"], 80)}</td>
                          <td className="p-2 border-y border-gray-300 whitespace-nowrap">{item["ipAddress"]}</td>
                          <td className="p-2 border-y border-gray-300 whitespace-nowrap">{getFormattedTime(item["created_at"])}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            ) : (
              <div className="flex">
                <table className="bg-white border border-gray-300">
                  <thead>
                    <tr>
                      <th className="p-2 border-0 border-gray-300">
                        <div className="flex">Pages</div>
                      </th>
                      <th className="p-2 border-0 border-gray-300">
                        <div className="flex">Count</div>
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {sortedTypes.map(([type, data]) => (
                      <tr
                        key={type}
                        className="cursor-pointer bg-zinc-50 hover:bg-zinc-100 hover:text-blue-500"
                        onClick={() => handleTypeClick(type)}
                      >
                        <td className="p-2 border-y border-gray-300 font-semibold">
                          {getTitleCase(type)}
                        </td>
                        <td className="p-2 border-y border-gray-300">
                          <div className="flex justify-center">
                            {data.count}
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>
        </div>
      )}
    </>
  );
};

export default Home;