import { html, css, LitElement } from "../../assets/lit-core-2.7.4.min.js";
import { unifiedPageStyles } from "./sharedPageStyles.js";

export class CustomizeView extends LitElement {
  static styles = [
    unifiedPageStyles,
    css`
      .danger-surface {
        border-color: var(--danger);
      }

      .warning-callout {
        position: relative;
        margin-top: 4px;
        padding: 8px 12px;
        border: 1px solid var(--danger);
        border-radius: var(--radius-sm);
        color: var(--danger);
        font-size: var(--font-size-xs);
        line-height: 1.4;
        background: rgba(239, 68, 68, 0.06);
      }

      .warning-callout::before {
        content: "";
        position: absolute;
        top: -6px;
        left: 16px;
        width: 10px;
        height: 10px;
        background: var(--bg-surface);
        border-top: 1px solid var(--danger);
        border-left: 1px solid var(--danger);
        transform: rotate(45deg);
      }

      .toggle-row {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-sm);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        background: var(--bg-elevated);
      }

      .toggle-input {
        width: 14px;
        height: 14px;
        accent-color: var(--text-primary);
        cursor: pointer;
      }

      .toggle-label {
        color: var(--text-primary);
        font-size: var(--font-size-sm);
        cursor: pointer;
        user-select: none;
      }

      .slider-wrap {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-xs);
      }

      .slider-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-sm);
      }

      .slider-value {
        font-family: var(--font-mono);
        font-size: var(--font-size-xs);
        color: var(--text-secondary);
        background: var(--bg-elevated);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        padding: 2px 8px;
      }

      .slider-input {
        -webkit-appearance: none;
        appearance: none;
        width: 100%;
        height: 4px;
        border-radius: 2px;
        background: var(--border);
        outline: none;
        cursor: pointer;
      }

      .slider-input::-webkit-slider-thumb {
        -webkit-appearance: none;
        appearance: none;
        width: 14px;
        height: 14px;
        border-radius: 50%;
        background: var(--text-primary);
        border: none;
      }

      .slider-input::-moz-range-thumb {
        width: 14px;
        height: 14px;
        border-radius: 50%;
        background: var(--text-primary);
        border: none;
      }

      .keybind-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: var(--space-sm) 0;
        border-bottom: 1px solid var(--border);
      }

      .keybind-row:last-of-type {
        border-bottom: none;
      }

      .keybind-name {
        color: var(--text-secondary);
        font-size: var(--font-size-sm);
      }

      .keybind-input {
        width: 140px;
        text-align: center;
        font-family: var(--font-mono);
        font-size: var(--font-size-xs);
      }

      .danger-button {
        border: 1px solid var(--danger);
        color: var(--danger);
        background: transparent;
        border-radius: var(--radius-sm);
        padding: 9px 12px;
        font-size: var(--font-size-sm);
        cursor: pointer;
        transition: background var(--transition);
      }

      .danger-button:hover {
        background: rgba(241, 76, 76, 0.11);
      }

      .danger-button:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }

      .status {
        margin-top: var(--space-sm);
        padding: var(--space-sm);
        border-radius: var(--radius-sm);
        border: 1px solid var(--border);
        font-size: var(--font-size-xs);
      }

      .status.success {
        border-color: var(--success);
        color: var(--success);
      }

      .status.error {
        border-color: var(--danger);
        color: var(--danger);
      }
    `,
  ];

  static properties = {
    selectedProfile: { type: String },
    selectedLanguage: { type: String },
    providerMode: { type: String },
    selectedImageQuality: { type: String },
    layoutMode: { type: String },
    keybinds: { type: Object },
    googleSearchEnabled: { type: Boolean },
    backgroundTransparency: { type: Number },
    fontSize: { type: Number },
    theme: { type: String },
    onProfileChange: { type: Function },
    onLanguageChange: { type: Function },
    onImageQualityChange: { type: Function },
    onLayoutModeChange: { type: Function },
    isClearing: { type: Boolean },
    isRestoring: { type: Boolean },
    clearStatusMessage: { type: String },
    clearStatusType: { type: String },
  };

  constructor() {
    super();
    this.selectedProfile = "interview";
    this.selectedLanguage = "en-US";
    this.selectedImageQuality = "medium";
    this.layoutMode = "normal";
    this.keybinds = this.getDefaultKeybinds();
    this.onProfileChange = () => {};
    this.onLanguageChange = () => {};
    this.onImageQualityChange = () => {};
    this.onLayoutModeChange = () => {};
    this.googleSearchEnabled = true;
    this.providerMode = "byok";
    this.isClearing = false;
    this.isRestoring = false;
    this.clearStatusMessage = "";
    this.clearStatusType = "";
    this.backgroundTransparency = 0.8;
    this.fontSize = 20;
    this.audioMode = "speaker_only";
    this.customPrompt = "";
    this.theme = "dark";
    this._loadFromStorage();
  }

  getThemes() {
    return cheatingDaddy.theme.getAll();
  }

  async _loadFromStorage() {
    try {
      const [prefs, keybinds] = await Promise.all([
        cheatingDaddy.storage.getPreferences(),
        cheatingDaddy.storage.getKeybinds(),
      ]);
      this.googleSearchEnabled = prefs.googleSearchEnabled ?? true;
      this.providerMode = prefs.providerMode || "byok";
      this.backgroundTransparency = prefs.backgroundTransparency ?? 0.8;
      this.fontSize = prefs.fontSize ?? 20;
      this.audioMode = prefs.audioMode ?? "speaker_only";
      this.customPrompt = prefs.customPrompt ?? "";
      this.theme = prefs.theme ?? "dark";
      if (keybinds) {
        this.keybinds = { ...this.getDefaultKeybinds(), ...keybinds };
      }
      this.updateBackgroundAppearance();
      this.updateFontSize();
      this.requestUpdate();
    } catch (error) {
      console.error("Error loading settings:", error);
    }
  }

  getProfiles() {
    return [
      { value: "interview", name: "Job Interview" },
      { value: "sales", name: "Sales Call" },
      { value: "meeting", name: "Business Meeting" },
      { value: "presentation", name: "Presentation" },
      { value: "negotiation", name: "Negotiation" },
      { value: "exam", name: "Exam Assistant" },
    ];
  }

  getLanguages() {
    return [
      { value: "auto", name: "Auto (Multilingual)" },
      { value: "en-US", name: "English (US)" },
      { value: "en-GB", name: "English (UK)" },
      { value: "en-AU", name: "English (Australia)" },
      { value: "en-IN", name: "English (India)" },
      { value: "de-DE", name: "German (Germany)" },
      { value: "es-US", name: "Spanish (US)" },
      { value: "es-ES", name: "Spanish (Spain)" },
      { value: "fr-FR", name: "French (France)" },
      { value: "fr-CA", name: "French (Canada)" },
      { value: "hi-IN", name: "Hindi (India)" },
      { value: "pt-BR", name: "Portuguese (Brazil)" },
      { value: "ar-XA", name: "Arabic (Generic)" },
      { value: "id-ID", name: "Indonesian (Indonesia)" },
      { value: "it-IT", name: "Italian (Italy)" },
      { value: "ja-JP", name: "Japanese (Japan)" },
      { value: "tr-TR", name: "Turkish (Turkey)" },
      { value: "vi-VN", name: "Vietnamese (Vietnam)" },
      { value: "bn-IN", name: "Bengali (India)" },
      { value: "gu-IN", name: "Gujarati (India)" },
      { value: "kn-IN", name: "Kannada (India)" },
      { value: "ml-IN", name: "Malayalam (India)" },
      { value: "mr-IN", name: "Marathi (India)" },
      { value: "ta-IN", name: "Tamil (India)" },
      { value: "te-IN", name: "Telugu (India)" },
      { value: "nl-NL", name: "Dutch (Netherlands)" },
      { value: "ko-KR", name: "Korean (South Korea)" },
      { value: "cmn-CN", name: "Mandarin Chinese (China)" },
      { value: "pl-PL", name: "Polish (Poland)" },
      { value: "ru-RU", name: "Russian (Russia)" },
      { value: "th-TH", name: "Thai (Thailand)" },
    ];
  }

  getDefaultKeybinds() {
    const isMac = cheatingDaddy.isMacOS || navigator.platform.includes("Mac");
    return {
      moveUp: isMac ? "Alt+Up" : "Ctrl+Up",
      moveDown: isMac ? "Alt+Down" : "Ctrl+Down",
      moveLeft: isMac ? "Alt+Left" : "Ctrl+Left",
      moveRight: isMac ? "Alt+Right" : "Ctrl+Right",
      toggleVisibility: isMac ? "Cmd+\\" : "Ctrl+\\",
      toggleClickThrough: isMac ? "Cmd+M" : "Ctrl+M",
      nextStep: isMac ? "Cmd+Enter" : "Ctrl+Enter",
      previousResponse: isMac ? "Cmd+[" : "Ctrl+[",
      nextResponse: isMac ? "Cmd+]" : "Ctrl+]",
      scrollUp: isMac ? "Cmd+Shift+Up" : "Ctrl+Shift+Up",
      scrollDown: isMac ? "Cmd+Shift+Down" : "Ctrl+Shift+Down",
      expandResponse: isMac ? "Cmd+E" : "Ctrl+E",
    };
  }

  getKeybindActions() {
    return [
      {
        key: "moveUp",
        name: "Move Window Up",
        description: "Move the app window up",
      },
      {
        key: "moveDown",
        name: "Move Window Down",
        description: "Move the app window down",
      },
      {
        key: "moveLeft",
        name: "Move Window Left",
        description: "Move the app window left",
      },
      {
        key: "moveRight",
        name: "Move Window Right",
        description: "Move the app window right",
      },
      {
        key: "toggleVisibility",
        name: "Toggle Visibility",
        description: "Show or hide the app window",
      },
      {
        key: "toggleClickThrough",
        name: "Toggle Click-through",
        description: "Enable or disable click-through mode",
      },
      {
        key: "nextStep",
        name: "Ask Next Step",
        description: "Take screenshot and ask for next step",
      },
      {
        key: "previousResponse",
        name: "Previous Response",
        description: "Move to previous AI response",
      },
      {
        key: "nextResponse",
        name: "Next Response",
        description: "Move to next AI response",
      },
      {
        key: "scrollUp",
        name: "Scroll Response Up",
        description: "Scroll response content upward",
      },
      {
        key: "scrollDown",
        name: "Scroll Response Down",
        description: "Scroll response content downward",
      },
      {
        key: "expandResponse",
        name: "Expand Response",
        description: "Expand the current response with more detail",
      },
    ];
  }

  async saveKeybinds() {
    await cheatingDaddy.storage.setKeybinds(this.keybinds);
    if (window.require) {
      const { ipcRenderer } = window.require("electron");
      ipcRenderer.send("update-keybinds", this.keybinds);
    }
  }

  handleProfileSelect(e) {
    this.selectedProfile = e.target.value;
    this.onProfileChange(this.selectedProfile);
  }

  handleLanguageSelect(e) {
    this.selectedLanguage = e.target.value;
    this.onLanguageChange(this.selectedLanguage);
  }

  handleImageQualitySelect(e) {
    this.selectedImageQuality = e.target.value;
    this.onImageQualityChange(this.selectedImageQuality);
  }

  handleLayoutModeSelect(e) {
    this.layoutMode = e.target.value;
    this.onLayoutModeChange(this.layoutMode);
  }

  async handleCustomPromptInput(e) {
    this.customPrompt = e.target.value;
    await cheatingDaddy.storage.updatePreference(
      "customPrompt",
      this.customPrompt,
    );
  }

  async handleAudioModeSelect(e) {
    this.audioMode = e.target.value;
    await cheatingDaddy.storage.updatePreference("audioMode", this.audioMode);
    this.requestUpdate();
  }

  async handleProviderModeChange(e) {
    this.providerMode = e.target.value;
    await cheatingDaddy.storage.updatePreference(
      "providerMode",
      this.providerMode,
    );
    this.requestUpdate();
  }

  async handleThemeChange(e) {
    this.theme = e.target.value;
    await cheatingDaddy.theme.save(this.theme);
    this.updateBackgroundAppearance();
    this.requestUpdate();
  }

  async handleGoogleSearchChange(e) {
    this.googleSearchEnabled = e.target.checked;
    await cheatingDaddy.storage.updatePreference(
      "googleSearchEnabled",
      this.googleSearchEnabled,
    );
    if (window.require) {
      try {
        const { ipcRenderer } = window.require("electron");
        await ipcRenderer.invoke(
          "update-google-search-setting",
          this.googleSearchEnabled,
        );
      } catch (error) {
        console.error("Failed to notify main process:", error);
      }
    }
    this.requestUpdate();
  }

  async handleBackgroundTransparencyChange(e) {
    this.backgroundTransparency = parseFloat(e.target.value);
    await cheatingDaddy.storage.updatePreference(
      "backgroundTransparency",
      this.backgroundTransparency,
    );
    this.updateBackgroundAppearance();
    this.requestUpdate();
  }

  updateBackgroundAppearance() {
    const colors = cheatingDaddy.theme.get(this.theme);
    cheatingDaddy.theme.applyBackgrounds(
      colors.background,
      this.backgroundTransparency,
    );
  }

  async handleFontSizeChange(e) {
    this.fontSize = parseInt(e.target.value, 10);
    await cheatingDaddy.storage.updatePreference("fontSize", this.fontSize);
    this.updateFontSize();
    this.requestUpdate();
  }

  updateFontSize() {
    document.documentElement.style.setProperty(
      "--response-font-size",
      `${this.fontSize}px`,
    );
  }

  handleKeybindChange(action, value) {
    this.keybinds = { ...this.keybinds, [action]: value };
    this.saveKeybinds();
    this.requestUpdate();
  }

  handleKeybindFocus(e) {
    e.target.placeholder = "Press key combination...";
    e.target.select();
  }

  handleKeybindInput(e) {
    e.preventDefault();
    const modifiers = [];
    if (e.ctrlKey) modifiers.push("Ctrl");
    if (e.metaKey) modifiers.push("Cmd");
    if (e.altKey) modifiers.push("Alt");
    if (e.shiftKey) modifiers.push("Shift");
    let mainKey = e.key;

    switch (e.code) {
      case "ArrowUp":
        mainKey = "Up";
        break;
      case "ArrowDown":
        mainKey = "Down";
        break;
      case "ArrowLeft":
        mainKey = "Left";
        break;
      case "ArrowRight":
        mainKey = "Right";
        break;
      case "Enter":
        mainKey = "Enter";
        break;
      case "Space":
        mainKey = "Space";
        break;
      case "Backslash":
        mainKey = "\\";
        break;
      default:
        if (e.key.length === 1) mainKey = e.key.toUpperCase();
        break;
    }

    if (["Control", "Meta", "Alt", "Shift"].includes(e.key)) return;

    const action = e.target.dataset.action;
    const keybind = [...modifiers, mainKey].join("+");
    this.handleKeybindChange(action, keybind);
    e.target.value = keybind;
    e.target.blur();
  }

  async resetKeybinds() {
    this.keybinds = this.getDefaultKeybinds();
    await cheatingDaddy.storage.setKeybinds(null);
    if (window.require) {
      const { ipcRenderer } = window.require("electron");
      ipcRenderer.send("update-keybinds", this.keybinds);
    }
    this.requestUpdate();
  }

  async restoreAllSettings() {
    if (this.isRestoring) return;
    this.isRestoring = true;
    this.clearStatusMessage = "";
    this.clearStatusType = "";
    this.requestUpdate();
    try {
      // Restore all preferences to defaults
      const defaults = {
        customPrompt: "",
        selectedProfile: "interview",
        selectedLanguage: "en-US",
        selectedScreenshotInterval: "5",
        selectedImageQuality: "medium",
        audioMode: "speaker_only",
        fontSize: 20,
        backgroundTransparency: 0.8,
        googleSearchEnabled: false,
        theme: "dark",
      };
      for (const [key, value] of Object.entries(defaults)) {
        await cheatingDaddy.storage.updatePreference(key, value);
      }

      // Restore keybinds
      this.keybinds = this.getDefaultKeybinds();
      await cheatingDaddy.storage.setKeybinds(null);
      if (window.require) {
        const { ipcRenderer } = window.require("electron");
        ipcRenderer.send("update-keybinds", this.keybinds);
      }

      // Apply to local state
      this.selectedProfile = defaults.selectedProfile;
      this.selectedLanguage = defaults.selectedLanguage;
      this.selectedImageQuality = defaults.selectedImageQuality;
      this.audioMode = defaults.audioMode;
      this.fontSize = defaults.fontSize;
      this.backgroundTransparency = defaults.backgroundTransparency;
      this.googleSearchEnabled = defaults.googleSearchEnabled;
      this.customPrompt = defaults.customPrompt;
      this.theme = defaults.theme;

      // Notify parent callbacks
      this.onProfileChange(defaults.selectedProfile);
      this.onLanguageChange(defaults.selectedLanguage);
      this.onImageQualityChange(defaults.selectedImageQuality);

      // Apply visual changes
      this.updateBackgroundAppearance();
      this.updateFontSize();
      await cheatingDaddy.theme.save(defaults.theme);

      this.clearStatusMessage = "All settings restored to defaults";
      this.clearStatusType = "success";
    } catch (error) {
      console.error("Error restoring settings:", error);
      this.clearStatusMessage = `Error restoring settings: ${error.message}`;
      this.clearStatusType = "error";
    } finally {
      this.isRestoring = false;
      this.requestUpdate();
    }
  }

  async clearLocalData() {
    if (this.isClearing) return;
    this.isClearing = true;
    this.clearStatusMessage = "";
    this.clearStatusType = "";
    this.requestUpdate();
    try {
      await cheatingDaddy.storage.clearAll();
      this.clearStatusMessage = "Successfully cleared all local data";
      this.clearStatusType = "success";
      this.requestUpdate();
      setTimeout(() => {
        this.clearStatusMessage = "Closing application...";
        this.requestUpdate();
        setTimeout(async () => {
          if (window.require) {
            const { ipcRenderer } = window.require("electron");
            await ipcRenderer.invoke("quit-application");
          }
        }, 1000);
      }, 2000);
    } catch (error) {
      console.error("Error clearing data:", error);
      this.clearStatusMessage = `Error clearing data: ${error.message}`;
      this.clearStatusType = "error";
    } finally {
      this.isClearing = false;
      this.requestUpdate();
    }
  }

  renderAISection() {
    return html`
      <section class="surface">
        <div class="surface-title">AI Engine</div>
        <div class="form-grid">
          <div class="form-group">
            <label class="form-label">Regime</label>
            <select
              class="control"
              .value=${this.providerMode}
              @change=${this.handleProviderModeChange}
            >
              <option value="byok">BYOK (API Keys)</option>
              <option value="local">Local AI (Ollama)</option>
            </select>
          </div>
        </div>
      </section>
    `;
  }

  renderAudioSection() {
    return html`
      <section class="surface">
        <div class="surface-title">Audio Input</div>
        <div class="form-grid">
          <div class="form-group">
            <label class="form-label">Audio Mode</label>
            <select
              class="control"
              .value=${this.audioMode}
              @change=${this.handleAudioModeSelect}
            >
              <option value="speaker_only">Speaker Only (Interviewer)</option>
              <option value="mic_only">Microphone Only (Me)</option>
              <option value="both">Both Speaker and Microphone</option>
            </select>
          </div>
          ${this.audioMode !== "speaker_only"
            ? html`
                <div class="warning-callout">
                  May cause unexpected behavior. Only change this if you know
                  what you're doing.
                </div>
              `
            : ""}
          <div class="form-group">
            <label class="form-label">Image Quality</label>
            <select
              class="control"
              .value=${this.selectedImageQuality}
              @change=${this.handleImageQualitySelect}
            >
              <option value="high">High Quality</option>
              <option value="medium">Medium Quality</option>
              <option value="low">Low Quality</option>
            </select>
          </div>
        </div>
      </section>
    `;
  }

  renderLanguageSection() {
    return html`
      <section class="surface">
        <div class="surface-title">Language</div>
        <div class="form-grid">
          <div class="form-group">
            <label class="form-label">Speech Language</label>
            <select
              class="control"
              .value=${this.selectedLanguage}
              @change=${this.handleLanguageSelect}
            >
              ${this.getLanguages().map(
                (language) =>
                  html`<option
                    value=${language.value}
                    ?selected=${language.value === this.selectedLanguage}
                  >
                    ${language.name}
                  </option>`,
              )}
            </select>
          </div>
        </div>
      </section>
    `;
  }

  renderAppearanceSection() {
    return html`
      <section class="surface">
        <div class="surface-title">Appearance</div>
        <div class="form-grid">
          <div class="form-group">
            <label class="form-label">Theme</label>
            <select
              class="control"
              .value=${this.theme}
              @change=${this.handleThemeChange}
            >
              ${this.getThemes().map(
                (theme) =>
                  html`<option value=${theme.value}>${theme.name}</option>`,
              )}
            </select>
          </div>
          <div class="form-group slider-wrap">
            <div class="slider-header">
              <label class="form-label">Background Transparency</label>
              <span class="slider-value"
                >${Math.round(this.backgroundTransparency * 100)}%</span
              >
            </div>
            <input
              class="slider-input"
              type="range"
              min="0"
              max="1"
              step="0.01"
              .value=${this.backgroundTransparency}
              @input=${this.handleBackgroundTransparencyChange}
            />
          </div>
          <div class="form-group slider-wrap">
            <div class="slider-header">
              <label class="form-label">Response Font Size</label>
              <span class="slider-value">${this.fontSize}px</span>
            </div>
            <input
              class="slider-input"
              type="range"
              min="12"
              max="32"
              step="1"
              .value=${this.fontSize}
              @input=${this.handleFontSizeChange}
            />
          </div>
        </div>
      </section>
    `;
  }

  renderKeyboardSection() {
    return html`
      <section class="surface">
        <div class="surface-title">Keyboard Shortcuts</div>
        ${this.getKeybindActions().map(
          (action) => html`
            <div class="keybind-row">
              <span class="keybind-name">${action.name}</span>
              <input
                type="text"
                class="control keybind-input"
                .value=${this.keybinds[action.key]}
                data-action=${action.key}
                @keydown=${this.handleKeybindInput}
                @focus=${this.handleKeybindFocus}
                readonly
              />
            </div>
          `,
        )}
        <div style="margin-top: var(--space-sm);">
          <button
            class="control"
            style="width:auto;padding:8px 10px;"
            @click=${this.resetKeybinds}
          >
            Reset to defaults
          </button>
        </div>
      </section>
    `;
  }

  renderPrivacySection() {
    return html`
      <section class="surface danger-surface">
        <div class="surface-title danger">Privacy and Data</div>
        <div style="display:flex;gap:var(--space-sm);flex-wrap:wrap;">
          <button
            class="danger-button"
            @click=${this.restoreAllSettings}
            ?disabled=${this.isRestoring}
          >
            ${this.isRestoring ? "Restoring..." : "Restore all settings"}
          </button>
          <button
            class="danger-button"
            @click=${this.clearLocalData}
            ?disabled=${this.isClearing}
          >
            ${this.isClearing ? "Clearing..." : "Delete all data"}
          </button>
        </div>
        ${this.clearStatusMessage
          ? html`
              <div
                class="status ${this.clearStatusType === "success"
                  ? "success"
                  : "error"}"
              >
                ${this.clearStatusMessage}
              </div>
            `
          : ""}
      </section>
    `;
  }

  render() {
    return html`
      <div class="unified-page">
        <div class="unified-wrap">
          <div class="page-title">Settings</div>
          ${this.renderAISection()} ${this.renderAudioSection()}
          ${this.renderLanguageSection()} ${this.renderAppearanceSection()}
          ${this.renderKeyboardSection()} ${this.renderPrivacySection()}
        </div>
      </div>
    `;
  }
}

customElements.define("customize-view", CustomizeView);
