import * as plugins from '../../../plugins.js';
import * as appstate from '../../../appstate.js';
import { viewHostCss } from '../../shared/index.js';
import {
  DeesElement,
  customElement,
  html,
  state,
  css,
  cssManager,
  type TemplateResult,
} from '@design.estate/dees-element';

@customElement('gitops-view-secrets')
export class GitopsViewSecrets extends DeesElement {
  @state()
  accessor connectionsState: appstate.IConnectionsState = {
    connections: [],
    activeConnectionId: null,
  };

  @state()
  accessor dataState: appstate.IDataState = {
    projects: [],
    groups: [],
    secrets: [],
    pipelines: [],
    pipelineJobs: [],
    currentJobLog: '',
  };

  @state()
  accessor selectedConnectionId: string = '';

  @state()
  accessor selectedScope: 'all' | 'project' | 'group' = 'all';

  @state()
  accessor selectedScopeId: string = '__all__';

  private _autoRefreshHandler: () => void;

  constructor() {
    super();
    const connSub = appstate.connectionsStatePart
      .select((s) => s)
      .subscribe((s) => { this.connectionsState = s; });
    this.rxSubscriptions.push(connSub);

    const dataSub = appstate.dataStatePart
      .select((s) => s)
      .subscribe((s) => { this.dataState = s; });
    this.rxSubscriptions.push(dataSub);

    this._autoRefreshHandler = () => this.handleAutoRefresh();
    document.addEventListener('gitops-auto-refresh', this._autoRefreshHandler);
  }

  public override disconnectedCallback() {
    super.disconnectedCallback();
    document.removeEventListener('gitops-auto-refresh', this._autoRefreshHandler);
  }

  private handleAutoRefresh(): void {
    this.loadSecrets();
  }

  public static styles = [
    cssManager.defaultStyles,
    viewHostCss,
  ];

  private get filteredSecrets() {
    let secrets = this.dataState.secrets;
    // Filter by scope (unless "all")
    if (this.selectedScope !== 'all') {
      secrets = secrets.filter((s) => s.scope === this.selectedScope);
    }
    // Filter by entity if specific one selected
    if (this.selectedScopeId !== '__all__') {
      secrets = secrets.filter((s) => s.scopeId === this.selectedScopeId);
    }
    return secrets;
  }

  public render(): TemplateResult {
    const connectionOptions = this.connectionsState.connections.map((c) => ({
      option: `${c.name} (${c.providerType})`,
      key: c.id,
    }));

    const scopeOptions = [
      { option: 'All Scopes', key: 'all' },
      { option: 'Project', key: 'project' },
      { option: 'Group', key: 'group' },
    ];

    const entities = this.selectedScope === 'group'
      ? this.dataState.groups.map((g) => ({ option: g.fullPath || g.name, key: g.id }))
      : this.selectedScope === 'project'
        ? this.dataState.projects.map((p) => ({ option: p.fullPath || p.name, key: p.id }))
        : [];

    const entityOptions = [
      { option: 'All', key: '__all__' },
      ...entities,
    ];

    const isAllSelected = this.selectedScope === 'all' || this.selectedScopeId === '__all__';

    return html`
      <div class="view-title">Secrets</div>
      <div class="view-description">Manage CI/CD secrets and variables</div>
      <div class="toolbar">
        <dees-input-dropdown
          .label=${'Connection'}
          .options=${connectionOptions}
          .selectedOption=${connectionOptions.find((o) => o.key === this.selectedConnectionId) || connectionOptions[0]}
          @selectedOption=${(e: CustomEvent) => {
            this.selectedConnectionId = e.detail.key;
            this.selectedScopeId = '__all__';
            this.loadEntities();
            this.loadSecrets();
          }}
        ></dees-input-dropdown>
        <dees-input-dropdown
          .label=${'Scope'}
          .options=${scopeOptions}
          .selectedOption=${scopeOptions.find((o) => o.key === this.selectedScope)}
          @selectedOption=${(e: CustomEvent) => {
            this.selectedScope = e.detail.key as 'all' | 'project' | 'group';
            this.selectedScopeId = '__all__';
            this.loadEntities();
            this.loadSecrets();
          }}
        ></dees-input-dropdown>
        ${this.selectedScope !== 'all' ? html`
          <dees-input-dropdown
            .label=${this.selectedScope === 'project' ? 'Project' : 'Group'}
            .options=${entityOptions}
            .selectedOption=${entityOptions.find((o) => o.key === this.selectedScopeId) || entityOptions[0]}
            @selectedOption=${(e: CustomEvent) => {
              this.selectedScopeId = e.detail.key;
            }}
          ></dees-input-dropdown>
        ` : ''}
        <dees-button
          .disabled=${isAllSelected}
          @click=${() => this.addSecret()}
        >Add Secret</dees-button>
        <dees-button @click=${() => this.loadSecrets()}>Refresh</dees-button>
      </div>
      <dees-table
        .heading1=${'Secrets'}
        .heading2=${'CI/CD variables for the selected entity'}
        .data=${this.filteredSecrets}
        .displayFunction=${(item: any) => ({
          Key: item.key,
          Scope: item.scopeName || item.scopeId,
          Value: item.masked ? '******' : item.value,
          Protected: item.protected ? 'Yes' : 'No',
          Environment: item.environment || '*',
        })}
        .dataActions=${[
          {
            name: 'Edit',
            iconName: 'lucide:edit',
            type: ['inRow', 'contextmenu'],
            actionFunc: async ({ item }: any) => { await this.editSecret(item); },
          },
          {
            name: 'Delete',
            iconName: 'lucide:trash2',
            type: ['inRow', 'contextmenu'],
            actionFunc: async ({ item }: any) => {
              await plugins.deesCatalog.DeesModal.createAndShow({
                heading: 'Delete Secret',
                content: html`<p style="color: #fff;">Are you sure you want to delete secret "${item.key}"?</p>`,
                menuOptions: [
                  { name: 'Cancel', action: async (modal: any) => { modal.destroy(); } },
                  {
                    name: 'Delete',
                    action: async (modal: any) => {
                      await appstate.dataStatePart.dispatchAction(appstate.deleteSecretAction, {
                        connectionId: this.selectedConnectionId,
                        scope: item.scope,
                        scopeId: item.scopeId,
                        key: item.key,
                      });
                      modal.destroy();
                    },
                  },
                ],
              });
            },
          },
        ]}
      ></dees-table>
    `;
  }

  async firstUpdated() {
    await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null);

    // Check for navigation context from projects/groups view
    const navCtx = appstate.uiStatePart.getState().navigationContext;
    if (navCtx?.connectionId && navCtx?.scope && navCtx?.scopeId) {
      this.selectedConnectionId = navCtx.connectionId;
      this.selectedScope = navCtx.scope;
      this.selectedScopeId = navCtx.scopeId;
      appstate.uiStatePart.dispatchAction(appstate.clearNavigationContextAction, null);
      await this.loadEntities();
      await this.loadSecrets();
      return;
    }

    const conns = appstate.connectionsStatePart.getState().connections;
    if (conns.length > 0 && !this.selectedConnectionId) {
      this.selectedConnectionId = conns[0].id;
      await this.loadEntities();
      await this.loadSecrets();
    }
  }

  private async loadEntities() {
    if (!this.selectedConnectionId) return;
    if (this.selectedScope === 'all') return;
    if (this.selectedScope === 'project') {
      await appstate.dataStatePart.dispatchAction(appstate.fetchProjectsAction, {
        connectionId: this.selectedConnectionId,
      });
    } else {
      await appstate.dataStatePart.dispatchAction(appstate.fetchGroupsAction, {
        connectionId: this.selectedConnectionId,
      });
    }
  }

  private async loadSecrets() {
    if (!this.selectedConnectionId) return;
    // Always fetch both scopes — client-side filtering handles the rest
    await appstate.dataStatePart.dispatchAction(appstate.fetchAllSecretsAction, {
      connectionId: this.selectedConnectionId,
    });
  }

  private async addSecret() {
    if (this.selectedScope === 'all' || this.selectedScopeId === '__all__') return;
    await plugins.deesCatalog.DeesModal.createAndShow({
      heading: 'Add Secret',
      content: html`
        <style>.form-row { margin-bottom: 16px; }</style>
        <div class="form-row">
          <dees-input-text .label=${'Key'} .key=${'key'}></dees-input-text>
        </div>
        <div class="form-row">
          <dees-input-text .label=${'Value'} .key=${'value'} type="password"></dees-input-text>
        </div>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modal: any) => { modal.destroy(); } },
        {
          name: 'Create',
          action: async (modal: any) => {
            const inputs = modal.shadowRoot.querySelectorAll('dees-input-text');
            const data: any = {};
            for (const input of inputs) { data[input.key] = input.value || ''; }
            await appstate.dataStatePart.dispatchAction(appstate.createSecretAction, {
              connectionId: this.selectedConnectionId,
              scope: this.selectedScope,
              scopeId: this.selectedScopeId,
              key: data.key,
              value: data.value,
            });
            modal.destroy();
          },
        },
      ],
    });
  }

  private async editSecret(item: any) {
    await plugins.deesCatalog.DeesModal.createAndShow({
      heading: `Edit Secret: ${item.key}`,
      content: html`
        <style>.form-row { margin-bottom: 16px; }</style>
        <div class="form-row">
          <dees-input-text .label=${'Value'} .key=${'value'} type="password"></dees-input-text>
        </div>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modal: any) => { modal.destroy(); } },
        {
          name: 'Update',
          action: async (modal: any) => {
            const input = modal.shadowRoot.querySelector('dees-input-text');
            await appstate.dataStatePart.dispatchAction(appstate.updateSecretAction, {
              connectionId: this.selectedConnectionId,
              scope: item.scope,
              scopeId: item.scopeId,
              key: item.key,
              value: input?.value || '',
            });
            modal.destroy();
          },
        },
      ],
    });
  }
}
