import React, { forwardRef, useState, useEffect } from "react";
import { BaseComponentProps } from "../../types";
import { Button } from "../ui/Button";
import { Card, CardContent, CardHeader, CardTitle } from "../ui/Card";

export interface ConsentCategory {
  id: string;
  name: string;
  description: string;
  required: boolean;
  enabled: boolean;
}

export interface ConsentManagerProps extends BaseComponentProps {
  categories?: ConsentCategory[];
  onConsentUpdate?: (consents: Record<string, boolean>) => void;
  onAcceptAll?: () => void;
  onRejectAll?: () => void;
  showBanner?: boolean;
  showSettings?: boolean;
  onSettingsToggle?: () => void;
  privacyPolicyUrl?: string;
  termsUrl?: string;
  companyName?: string;
  bannerText?: string;
  settingsText?: string;
}

const defaultCategories: ConsentCategory[] = [
  {
    id: "necessary",
    name: "Necessary Cookies",
    description:
      "These cookies are essential for the website to function properly. They cannot be disabled.",
    required: true,
    enabled: true,
  },
  {
    id: "analytics",
    name: "Analytics Cookies",
    description:
      "These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously.",
    required: false,
    enabled: false,
  },
  {
    id: "marketing",
    name: "Marketing Cookies",
    description:
      "These cookies are used to track visitors across websites to display relevant and engaging advertisements.",
    required: false,
    enabled: false,
  },
  {
    id: "preferences",
    name: "Preference Cookies",
    description:
      "These cookies allow the website to remember choices you make to provide enhanced, more personal features.",
    required: false,
    enabled: false,
  },
];

export const ConsentManager = forwardRef<HTMLDivElement, ConsentManagerProps>(
  (
    {
      className = "",
      categories = defaultCategories,
      onConsentUpdate,
      onAcceptAll,
      onRejectAll,
      showBanner = true,
      showSettings = false,
      onSettingsToggle,
      privacyPolicyUrl,
      termsUrl,
      bannerText = "We use cookies and similar technologies to enhance your browsing experience, analyze site traffic, and personalize content.",
      settingsText = "Manage your cookie preferences below. You can change these settings at any time.",
      ...props
    },
    ref
  ) => {
    const [consentData, setConsentData] =
      useState<ConsentCategory[]>(categories);
    const [hasInteracted, setHasInteracted] = useState(false);

    useEffect(() => {
      // Load saved consent preferences from localStorage
      const savedConsent = localStorage.getItem("consent-preferences");
      if (savedConsent) {
        try {
          const parsed = JSON.parse(savedConsent);
          setConsentData((prev) =>
            prev.map((category) => ({
              ...category,
              enabled: category.required || parsed[category.id] || false,
            }))
          );
          setHasInteracted(true);
        } catch (error) {
          console.error("Failed to parse saved consent preferences:", error);
        }
      }
    }, []);

    const saveConsent = (newConsentData: ConsentCategory[]) => {
      const consentObject = newConsentData.reduce((acc, category) => {
        acc[category.id] = category.enabled;
        return acc;
      }, {} as Record<string, boolean>);

      localStorage.setItem(
        "consent-preferences",
        JSON.stringify(consentObject)
      );
      onConsentUpdate?.(consentObject);
      setHasInteracted(true);
    };

    const handleAcceptAll = () => {
      const updatedData = consentData.map((category) => ({
        ...category,
        enabled: true,
      }));
      setConsentData(updatedData);
      saveConsent(updatedData);
      onAcceptAll?.();
    };

    const handleRejectAll = () => {
      const updatedData = consentData.map((category) => ({
        ...category,
        enabled: category.required,
      }));
      setConsentData(updatedData);
      saveConsent(updatedData);
      onRejectAll?.();
    };

    const handleCategoryToggle = (categoryId: string) => {
      const updatedData = consentData.map((category) =>
        category.id === categoryId && !category.required
          ? { ...category, enabled: !category.enabled }
          : category
      );
      setConsentData(updatedData);
    };

    const handleSaveSettings = () => {
      saveConsent(consentData);
      onSettingsToggle?.();
    };

    const renderToggleSwitch = (
      enabled: boolean,
      onChange: () => void,
      disabled = false
    ) => (
      <button
        type="button"
        className={`relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 ${
          enabled ? "bg-primary-600" : "bg-gray-200 dark:bg-gray-700"
        } ${disabled ? "opacity-50 cursor-not-allowed" : ""}`}
        onClick={onChange}
        disabled={disabled}
      >
        <span
          className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${
            enabled ? "translate-x-5" : "translate-x-0"
          }`}
        />
      </button>
    );

    const renderBanner = () => {
      if (!showBanner || hasInteracted) return null;

      return (
        <div className="fixed bottom-0 left-0 right-0 z-50 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 shadow-lg">
          <div className="max-w-7xl mx-auto p-4">
            <div className="flex flex-col lg:flex-row items-center justify-between gap-4">
              <div className="flex-1">
                <p className="text-sm text-gray-700 dark:text-gray-300">
                  {bannerText}
                  {(privacyPolicyUrl || termsUrl) && (
                    <span className="ml-1">
                      Learn more in our{" "}
                      {privacyPolicyUrl && (
                        <a
                          href={privacyPolicyUrl}
                          className="text-primary-600 hover:text-primary-800 dark:text-primary-400 dark:hover:text-primary-300 underline"
                          target="_blank"
                          rel="noopener noreferrer"
                        >
                          Privacy Policy
                        </a>
                      )}
                      {privacyPolicyUrl && termsUrl && " and "}
                      {termsUrl && (
                        <a
                          href={termsUrl}
                          className="text-primary-600 hover:text-primary-800 dark:text-primary-400 dark:hover:text-primary-300 underline"
                          target="_blank"
                          rel="noopener noreferrer"
                        >
                          Terms of Service
                        </a>
                      )}
                      .
                    </span>
                  )}
                </p>
              </div>

              <div className="flex items-center space-x-3">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => onSettingsToggle?.()}
                >
                  Settings
                </Button>
                <Button variant="outline" size="sm" onClick={handleRejectAll}>
                  Reject All
                </Button>
                <Button size="sm" onClick={handleAcceptAll}>
                  Accept All
                </Button>
              </div>
            </div>
          </div>
        </div>
      );
    };

    const renderSettings = () => {
      if (!showSettings) return null;

      return (
        <div className="fixed inset-0 z-50 bg-gray-600 bg-opacity-50 overflow-y-auto">
          <div className="flex items-center justify-center min-h-screen p-4">
            <Card className="w-full max-w-2xl">
              <CardHeader>
                <div className="flex items-center justify-between">
                  <CardTitle>Cookie Preferences</CardTitle>
                  <button
                    onClick={() => onSettingsToggle?.()}
                    className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
                  >
                    <svg
                      className="w-6 h-6"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M6 18L18 6M6 6l12 12"
                      />
                    </svg>
                  </button>
                </div>
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  {settingsText}
                </p>
              </CardHeader>

              <CardContent>
                <div className="space-y-6">
                  {consentData.map((category) => (
                    <div
                      key={category.id}
                      className="flex items-start justify-between"
                    >
                      <div className="flex-1 mr-4">
                        <h3 className="font-medium text-gray-900 dark:text-white mb-1">
                          {category.name}
                          {category.required && (
                            <span className="ml-2 inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200">
                              Required
                            </span>
                          )}
                        </h3>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          {category.description}
                        </p>
                      </div>

                      <div className="flex-shrink-0">
                        {renderToggleSwitch(
                          category.enabled,
                          () => handleCategoryToggle(category.id),
                          category.required
                        )}
                      </div>
                    </div>
                  ))}
                </div>

                <div className="flex items-center justify-end space-x-3 mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
                  <Button variant="outline" onClick={handleRejectAll}>
                    Reject All
                  </Button>
                  <Button variant="outline" onClick={handleAcceptAll}>
                    Accept All
                  </Button>
                  <Button onClick={handleSaveSettings}>Save Preferences</Button>
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      );
    };

    return (
      <div ref={ref} className={className} {...props}>
        {renderBanner()}
        {renderSettings()}
      </div>
    );
  }
);

ConsentManager.displayName = "ConsentManager";
