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

declare global {
  interface HTMLElementTagNameMap {
    'ops-view-networktargets': OpsViewNetworkTargets;
  }
}

@customElement('ops-view-networktargets')
export class OpsViewNetworkTargets extends DeesElement {
  @state()
  accessor profilesState: appstate.IProfilesTargetsState = appstate.profilesTargetsStatePart.getState()!;

  constructor() {
    super();
    const sub = appstate.profilesTargetsStatePart.select().subscribe((newState) => {
      this.profilesState = newState;
    });
    this.rxSubscriptions.push(sub);
  }

  async connectedCallback() {
    await super.connectedCallback();
    await appstate.profilesTargetsStatePart.dispatchAction(appstate.fetchProfilesAndTargetsAction, null);
  }

  public static styles = [
    cssManager.defaultStyles,
    viewHostCss,
    css`
      .targetsContainer {
        display: flex;
        flex-direction: column;
        gap: 24px;
      }
    `,
  ];

  public render(): TemplateResult {
    const targets = this.profilesState.targets;

    const statsTiles: IStatsTile[] = [
      {
        id: 'totalTargets',
        title: 'Total Targets',
        type: 'number',
        value: targets.length,
        icon: 'lucide:server',
        description: 'Reusable network targets',
        color: '#8b5cf6',
      },
    ];

    return html`
      <dees-heading level="3">Network Targets</dees-heading>
      <div class="targetsContainer">
        <dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
        <dees-table
          .heading1=${'Network Targets'}
          .heading2=${'Reusable host:port destinations for routes'}
          .data=${targets}
          .showColumnFilters=${true}
          .displayFunction=${(target: interfaces.data.INetworkTarget) => ({
            Name: target.name,
            Host: Array.isArray(target.host) ? target.host.join(', ') : target.host,
            Port: target.port,
            Description: target.description || '-',
          })}
          .dataActions=${[
            {
              name: 'Create Target',
              iconName: 'lucide:plus',
              type: ['header' as const],
              actionFunc: async () => {
                await this.showCreateTargetDialog();
              },
            },
            {
              name: 'Refresh',
              iconName: 'lucide:rotateCw',
              type: ['header' as const],
              actionFunc: async () => {
                await appstate.profilesTargetsStatePart.dispatchAction(appstate.fetchProfilesAndTargetsAction, null);
              },
            },
            {
              name: 'Edit',
              iconName: 'lucide:pencil',
              type: ['inRow', 'contextmenu'] as any,
              actionFunc: async (actionData: any) => {
                const target = actionData.item as interfaces.data.INetworkTarget;
                await this.showEditTargetDialog(target);
              },
            },
            {
              name: 'Delete',
              iconName: 'lucide:trash2',
              type: ['inRow', 'contextmenu'] as any,
              actionFunc: async (actionData: any) => {
                const target = actionData.item as interfaces.data.INetworkTarget;
                await this.deleteTarget(target);
              },
            },
          ]}
        ></dees-table>
      </div>
    `;
  }

  private async showCreateTargetDialog() {
    const { DeesModal } = await import('@design.estate/dees-catalog');
    DeesModal.createAndShow({
      heading: 'Create Network Target',
      content: html`
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
          <dees-input-text .key=${'host'} .label=${'Host'} .required=${true}></dees-input-text>
          <dees-input-text .key=${'port'} .label=${'Port'} .required=${true} .value=${'443'}></dees-input-text>
          <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
        </dees-form>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        {
          name: 'Create',
          action: async (modalArg: any) => {
            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
            if (!form) return;
            const data = await form.collectFormData();

            await appstate.profilesTargetsStatePart.dispatchAction(appstate.createTargetAction, {
              name: String(data.name),
              description: data.description ? String(data.description) : undefined,
              host: String(data.host),
              port: parseInt(String(data.port)) || 443,
            });
            modalArg.destroy();
          },
        },
      ],
    });
  }

  private async showEditTargetDialog(target: interfaces.data.INetworkTarget) {
    const hostStr = Array.isArray(target.host) ? target.host.join(', ') : target.host;

    const { DeesModal } = await import('@design.estate/dees-catalog');
    DeesModal.createAndShow({
      heading: `Edit Target: ${target.name}`,
      content: html`
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Name'} .value=${target.name}></dees-input-text>
          <dees-input-text .key=${'host'} .label=${'Host'} .value=${hostStr}></dees-input-text>
          <dees-input-text .key=${'port'} .label=${'Port'} .value=${String(target.port)}></dees-input-text>
          <dees-input-text .key=${'description'} .label=${'Description'} .value=${target.description || ''}></dees-input-text>
        </dees-form>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        {
          name: 'Save',
          action: async (modalArg: any) => {
            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
            if (!form) return;
            const data = await form.collectFormData();

            await appstate.profilesTargetsStatePart.dispatchAction(appstate.updateTargetAction, {
              id: target.id,
              name: String(data.name),
              description: data.description ? String(data.description) : undefined,
              host: String(data.host),
              port: parseInt(String(data.port)) || 443,
            });
            modalArg.destroy();
          },
        },
      ],
    });
  }

  private async deleteTarget(target: interfaces.data.INetworkTarget) {
    await appstate.profilesTargetsStatePart.dispatchAction(appstate.deleteTargetAction, {
      id: target.id,
      force: false,
    });

    const currentState = appstate.profilesTargetsStatePart.getState()!;
    if (currentState.error?.includes('in use')) {
      const { DeesModal } = await import('@design.estate/dees-catalog');
      DeesModal.createAndShow({
        heading: 'Target In Use',
        content: html`<p>${currentState.error} Force delete?</p>`,
        menuOptions: [
          {
            name: 'Force Delete',
            action: async (modalArg: any) => {
              await appstate.profilesTargetsStatePart.dispatchAction(appstate.deleteTargetAction, {
                id: target.id,
                force: true,
              });
              modalArg.destroy();
            },
          },
          { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        ],
      });
    }
  }
}
