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

export interface NotificationSetting {
  id: string;
  label: string;
  description?: string;
  enabled: boolean;
  type: "email" | "push" | "sms" | "in-app";
}

export interface NotificationCategory {
  id: string;
  title: string;
  description?: string;
  settings: NotificationSetting[];
}

export interface NotificationSettingsProps extends BaseComponentProps {
  categories: NotificationCategory[];
  onSave?: (settings: NotificationSetting[]) => void;
  loading?: boolean;
  allowGlobalToggle?: boolean;
}

export const NotificationSettings = forwardRef<
  HTMLDivElement,
  NotificationSettingsProps
>(
  (
    {
      className = "",
      categories,
      onSave,
      loading = false,
      allowGlobalToggle = true,
      ...props
    },
    ref
  ) => {
    const [settings, setSettings] = useState<NotificationSetting[]>(
      categories.flatMap((category) => category.settings)
    );
    const [hasChanges, setHasChanges] = useState(false);

    const handleToggle = (settingId: string) => {
      setSettings((prev) => {
        const updated = prev.map((setting) =>
          setting.id === settingId
            ? { ...setting, enabled: !setting.enabled }
            : setting
        );
        setHasChanges(true);
        return updated;
      });
    };

    const handleGlobalToggle = (
      type: NotificationSetting["type"],
      enabled: boolean
    ) => {
      setSettings((prev) => {
        const updated = prev.map((setting) =>
          setting.type === type ? { ...setting, enabled } : setting
        );
        setHasChanges(true);
        return updated;
      });
    };

    const handleSave = () => {
      onSave?.(settings);
      setHasChanges(false);
    };

    const handleReset = () => {
      setSettings(categories.flatMap((category) => category.settings));
      setHasChanges(false);
    };

    const getTypeIcon = (type: NotificationSetting["type"]) => {
      switch (type) {
        case "email":
          return (
            <svg
              className="w-5 h-5"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M3 8l7.89 7.89a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
              />
            </svg>
          );
        case "push":
          return (
            <svg
              className="w-5 h-5"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M15 17h5l-5 5v-5zM4.868 19.504A8.966 8.966 0 003 12c0-4.97 4.03-9 9-9s9 4.03 9 9a8.966 8.966 0 00-1.868 7.504"
              />
            </svg>
          );
        case "sms":
          return (
            <svg
              className="w-5 h-5"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
              />
            </svg>
          );
        case "in-app":
          return (
            <svg
              className="w-5 h-5"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M15 17h5l-5 5v-5zM4.868 19.504A8.966 8.966 0 003 12c0-4.97 4.03-9 9-9s9 4.03 9 9a8.966 8.966 0 00-1.868 7.504"
              />
            </svg>
          );
      }
    };

    const getSettingsByType = (type: NotificationSetting["type"]) => {
      return settings.filter((setting) => setting.type === type);
    };

    const isTypeEnabled = (type: NotificationSetting["type"]) => {
      const typeSettings = getSettingsByType(type);
      return typeSettings.some((setting) => setting.enabled);
    };

    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 renderGlobalControls = () => {
      if (!allowGlobalToggle) return null;

      const types: NotificationSetting["type"][] = [
        "email",
        "push",
        "sms",
        "in-app",
      ];

      return (
        <Card className="mb-6">
          <CardHeader>
            <CardTitle>Quick Controls</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
              {types.map((type) => (
                <div
                  key={type}
                  className="flex items-center justify-between p-3 border border-gray-200 dark:border-gray-700 rounded-lg"
                >
                  <div className="flex items-center space-x-3">
                    <div className="text-gray-500 dark:text-gray-400">
                      {getTypeIcon(type)}
                    </div>
                    <span className="text-sm font-medium text-gray-900 dark:text-white capitalize">
                      {type === "in-app" ? "In-App" : type}
                    </span>
                  </div>
                  {renderToggleSwitch(
                    isTypeEnabled(type),
                    () => handleGlobalToggle(type, !isTypeEnabled(type)),
                    loading
                  )}
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      );
    };

    return (
      <div ref={ref} className={className} {...props}>
        {renderGlobalControls()}

        <div className="space-y-6">
          {categories.map((category) => (
            <Card key={category.id}>
              <CardHeader>
                <CardTitle>{category.title}</CardTitle>
                {category.description && (
                  <p className="text-sm text-gray-600 dark:text-gray-400">
                    {category.description}
                  </p>
                )}
              </CardHeader>
              <CardContent>
                <div className="space-y-4">
                  {category.settings.map((setting) => {
                    const currentSetting = settings.find(
                      (s) => s.id === setting.id
                    );
                    if (!currentSetting) return null;

                    return (
                      <div
                        key={setting.id}
                        className="flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-700 last:border-b-0"
                      >
                        <div className="flex items-center space-x-3">
                          <div className="text-gray-500 dark:text-gray-400">
                            {getTypeIcon(setting.type)}
                          </div>
                          <div>
                            <h4 className="text-sm font-medium text-gray-900 dark:text-white">
                              {setting.label}
                            </h4>
                            {setting.description && (
                              <p className="text-sm text-gray-500 dark:text-gray-400">
                                {setting.description}
                              </p>
                            )}
                          </div>
                        </div>
                        {renderToggleSwitch(
                          currentSetting.enabled,
                          () => handleToggle(setting.id),
                          loading
                        )}
                      </div>
                    );
                  })}
                </div>
              </CardContent>
            </Card>
          ))}
        </div>

        {hasChanges && (
          <div className="sticky bottom-0 mt-6 p-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg">
            <div className="flex items-center justify-between">
              <p className="text-sm text-gray-600 dark:text-gray-400">
                You have unsaved changes
              </p>
              <div className="flex space-x-3">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleReset}
                  disabled={loading}
                >
                  Reset
                </Button>
                <Button
                  size="sm"
                  onClick={handleSave}
                  loading={loading}
                  disabled={loading}
                >
                  Save Changes
                </Button>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }
);

NotificationSettings.displayName = "NotificationSettings";
