import type { Ref } from 'vue';
import type { Layer } from '@/types/sprites';

const POCKETBASE_URL = 'https://pb1.adhd.sh';
const COLLECTION = 'spritesheets';

export interface SpritesheetConfig {
  version: number;
  columns: number;
  negativeSpacingEnabled: boolean;
  backgroundColor: string;
  manualCellSizeEnabled: boolean;
  manualCellWidth: number;
  manualCellHeight: number;
}

export interface SharedSprite {
  id: string;
  width: number;
  height: number;
  x: number;
  y: number;
  rotation: number;
  flipX: boolean;
  flipY: boolean;
  base64: string;
  name?: string;
}

export interface SharedLayer {
  id: string;
  name: string;
  visible: boolean;
  locked: boolean;
  sprites: SharedSprite[];
}

export interface SpritesheetRecord {
  id: string;
  config: SpritesheetConfig;
  sprites: SharedLayer[];
  created: string;
  updated: string;
}

export interface ShareResult {
  id: string;
  url: string;
}

/**
 * Build the shareable URL for a spritesheet
 */
export const buildShareUrl = (id: string): string => {
  return `${window.location.origin}/share/${id}`;
};

/**
 * Share a spritesheet by uploading to PocketBase
 */
export const shareSpritesheet = async (layersRef: Ref<Layer[]>, columns: Ref<number>, negativeSpacingEnabled: Ref<boolean>, backgroundColor?: Ref<string>, manualCellSizeEnabled?: Ref<boolean>, manualCellWidth?: Ref<number>, manualCellHeight?: Ref<number>): Promise<ShareResult> => {
  // Build layers data with base64 sprites (same format as exportSpritesheetJSON)
  const layersData = await Promise.all(
    layersRef.value.map(async layer => {
      const sprites = await Promise.all(
        layer.sprites.map(async sprite => {
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          if (!ctx) return null;
          canvas.width = sprite.width;
          canvas.height = sprite.height;
          if (sprite.rotation || sprite.flipX || sprite.flipY) {
            ctx.save();
            ctx.translate(sprite.width / 2, sprite.height / 2);
            ctx.rotate((sprite.rotation * Math.PI) / 180);
            ctx.scale(sprite.flipX ? -1 : 1, sprite.flipY ? -1 : 1);
            ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
            ctx.restore();
          } else {
            ctx.drawImage(sprite.img, 0, 0);
          }
          const base64 = canvas.toDataURL('image/png');
          // Since we bake transformations into the image, set them to 0/false in metadata
          return {
            id: sprite.id,
            width: sprite.width,
            height: sprite.height,
            x: sprite.x,
            y: sprite.y,
            rotation: 0,
            flipX: false,
            flipY: false,
            base64,
            name: sprite.file.name,
          };
        })
      );
      return {
        id: layer.id,
        name: layer.name,
        visible: layer.visible,
        locked: layer.locked,
        sprites: sprites.filter(Boolean),
      };
    })
  );

  const config: SpritesheetConfig = {
    version: 2,
    columns: columns.value,
    negativeSpacingEnabled: negativeSpacingEnabled.value,
    backgroundColor: backgroundColor?.value || 'transparent',
    manualCellSizeEnabled: manualCellSizeEnabled?.value || false,
    manualCellWidth: manualCellWidth?.value || 64,
    manualCellHeight: manualCellHeight?.value || 64,
  };

  const response = await fetch(`${POCKETBASE_URL}/api/collections/${COLLECTION}/records`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      config,
      sprites: layersData,
    }),
  });

  if (!response.ok) {
    const text = await response.text().catch(() => '');
    throw new Error(text || `Request failed with status ${response.status}`);
  }

  const record = await response.json();
  return {
    id: record.id,
    url: buildShareUrl(record.id),
  };
};

/**
 * Fetch a shared spritesheet from PocketBase
 */
export const fetchSpritesheet = async (id: string): Promise<SpritesheetRecord> => {
  const response = await fetch(`${POCKETBASE_URL}/api/collections/${COLLECTION}/records/${id}`);

  if (!response.ok) {
    if (response.status === 404) {
      throw new Error('Spritesheet not found');
    }
    const text = await response.text().catch(() => '');
    throw new Error(text || `Request failed with status ${response.status}`);
  }

  return response.json();
};

/**
 * Composable hook for share functionality
 */
export const useShare = (layersRef: Ref<Layer[]>, columns: Ref<number>, negativeSpacingEnabled: Ref<boolean>, backgroundColor?: Ref<string>, manualCellSizeEnabled?: Ref<boolean>, manualCellWidth?: Ref<number>, manualCellHeight?: Ref<number>) => {
  const share = () => shareSpritesheet(layersRef, columns, negativeSpacingEnabled, backgroundColor, manualCellSizeEnabled, manualCellWidth, manualCellHeight);

  return {
    share,
    fetchSpritesheet,
    buildShareUrl,
  };
};
